Memento Design Pattern in C++



Memento Design Pattern is a behavioral design pattern that allows an object to capture its internal state and save it externally so that it can be restored later without violating encapsulation. This pattern is particularly useful when you want to implement features like undo/redo functionality in applications.

For example, take an application where users can edit documents. By using the Memento Design Pattern, the application can save the state of the document at various points in time. If the user wants to undo their last action, the application can restore the document to its previous state using the saved memento. This way, the internal state of the document is preserved without exposing its details to other parts of the application.

Memento Design Pattern Illustration

Components of Memento Design Pattern

The Memento Design Pattern consists of three main components −

  • Originator − The main object you want to save and restore. It can make a memento (a snapshot of its current state) and later use that memento to go back to how it was before. For example, in a text editor, the Originator is the editor itself that holds your text.
  • Memento − A special object that remembers the state of the Originator at a certain time. Once made, its contents cannot be changed, so you can always trust it to bring things back exactly as they were. Think of it like a bookmark or a save point.
  • Caretaker − The helper that keeps track of all the mementos (saved states). It stores them safely and can ask the Originator to go back to a previous state when needed. The Caretaker never looks inside the mementos or changes them; it just holds onto them and gives them back when you want to undo or redo something.

C++ Implementation of Memento Design Pattern

We will use all three components of the Memento Design Pattern to implement a simple text editor that allows users to type text and undo their last action.

In this editor, the Originator will be the TextEditor class, which maintains the current text and creates mementos to save its state. The Memento will be the TextMemento class, which stores the text state. The Caretaker will be the EditorHistory class, which manages the mementos and allows undo functionality.

Steps to Implement Memento Design Pattern in C++

Follow these steps to implement the Memento Design Pattern in C++

Steps to Implement Memento Design Pattern
  • Create a Memento class ( TextMemento ) that will save the from the editor. This class just keeps a copy of the text so you can get it back later.
  • Make an Originator class ( TextEditor ). This is your main editor where you type and change text. It can create a memento to save its current text, and it can restore its text from a memento if you want to go back.
  • Add a Caretaker class ( EditorHistory ). This class remembers all the saved versions (mementos) of your text. It lets you undo by giving you back the last saved version.
  • Write a main function to show how it works. Here, you will type some text, save it, and then use undo to go back to earlier versions.

C++ Code of Memento Design Pattern

Below is the C++ code that implements the Memento Design Pattern for a simple text editor with undo functionality −

#include <iostream>
#include <string>
#include <vector>
using namespace std;

// Memento class
class TextMemento {
private:
   string textState;
public:
   TextMemento(const string &state) : textState(state) {}
   string getState() const { return textState; }
};

// Originator class
class TextEditor {
private:
   string text;
public:
   void type(const string &newText) {
       text += newText;
   }
   string getText() const {
       return text;
   }
   TextMemento save() {
       return TextMemento(text);
   }
   void restore(const TextMemento &memento) {
       text = memento.getState();
   }
};

// Caretaker class
class EditorHistory {
private:
   vector<TextMemento> history;
public:
   void push(const TextMemento &memento) {
      history.push_back(memento);
   }
   TextMemento pop() {
      if (!history.empty()) {
         TextMemento memento = history.back();
         history.pop_back();
         return memento;
      }
      return TextMemento("");
   }
};

// Main function to demonstrate Memento Design Pattern
int main() {
   TextEditor editor;
   EditorHistory history;

   editor.type("Hello, ");
   history.push(editor.save());
   editor.type("World!");
   history.push(editor.save());

   cout << "Current Text: " << editor.getText() << endl;

   editor.restore(history.pop());
   cout << "After Undo: " << editor.getText() << endl;

   editor.restore(history.pop());
   cout << "After Undo: " << editor.getText() << endl;

   return 0;
}

In this code, we have defined the TextMemento class to store the text state, the TextEditor class to manage the text and create/restore mementos, and the EditorHistory class to manage the history of mementos for undo functionality. The main function demonstrates how to use these classes to type text and undo actions.

Current Text: Hello, World!
After Undo: Hello, 
After Undo: 

Pros and Cons of Memento Design Pattern

Following are the advantages and disadvantages of using the Memento Design Pattern −

Pros Cons
Undo is easy and helpful. You can quickly go back to an earlier version if you make a mistake or want to change something. It can use a lot of memory if you keep saving many versions. This might make your program slower or take up more space.
Your object's details stay safe. Other parts of your program cannot change or see the inside details by mistake, so your data is protected. You need to make extra classes to use this pattern. This can make your code a little more complicated and harder to manage.
Undo and redo features are simple to add. This pattern makes it easy for users to fix mistakes or try different things without worry. Saving big or many states can slow things down. If your program saves a lot of information often, it might not run as fast.

When to Use Memento Design Pattern

The Memento Design Pattern is very useful in everyday programs where you want to let people fix mistakes or go back to something they did before. It is especially helpful for adding undo and redo features, which make programs much easier and safer to use.

For example, if someone is writing in a text editor or drawing in a paint app, they might make a mistake. With this pattern, the program can save the state of their work at different times. If they want to fix a mistake, they can restore an earlier version without anyone seeing or changing the private details inside the program.

This pattern is also great for keeping a history of changes. People can easily go back to an earlier version of their work if they change their mind or want to try something different. It helps make programs more friendly and less stressful to use.

Real-World Examples of Memento Design Pattern

Here are some real-world examples where the Memento Design Pattern is used in simple, everyday language −

Real-World Use Cases of Memento Design Pattern
  • Text editors like Notepad or Word let you undo and redo what you type. If you make a mistake, you can easily go back to how it was before.
  • Drawing or graphic design apps let you revert to an earlier version of your picture. If you don't like your last change, you can bring back the old version.
  • Video games often let you save your progress. If you lose or want to try again, you can load your saved game and start from there.
  • Version control systems (like Git) help you track changes to your files. If you want to go back to an older version, you can restore it easily.
  • Databases use this pattern to roll back to a safe state if something goes wrong, so your data stays safe.
  • Settings or configuration managers let you save your system settings. If you change something and it doesn't work, you can restore the old settings.

Conclusion

In this chapter, you learned about the Memento Design Pattern, its three main parts, and how to use it in C++. You also saw the good and bad sides, when to use it, and some real-life examples. The Memento Pattern is a great way to let users undo and redo actions, keep their data safe, and make your programs easier to use.

Advertisements