DEV Community

Nick
Nick

Posted on

What is Memento Pattern in C#?

The Memento Pattern is a behavioral design pattern that allows us to capture and restore an object's internal state without violating encapsulation. This pattern is useful when we want to provide an undo/redo functionality or to revert an object to its previous state.

In C#, we can implement the Memento Pattern using three main components: the Originator, the Memento, and the Caretaker.

The Originator is the object whose state we want to save. It should have methods to save and restore its state. Let's consider an example where we have a class called TextEditor:

public class TextEditor
{
    private string _text;

    public string Text
    {
        get { return _text; }
        set { _text = value; }
    }

    public Memento CreateMemento()
    {
        return new Memento(_text);
    }

    public void RestoreMemento(Memento memento)
    {
        _text = memento.GetState();
    }
}
Enter fullscreen mode Exit fullscreen mode

The TextEditor class has a Text property representing the current state of the text. It also has methods to create a memento and restore the state from a memento.

The Memento class is a container that stores the state of the Originator. It should have a method to retrieve the saved state. Let's create the Memento class:

public class Memento
{
    private string _state;

    public Memento(string state)
    {
        _state = state;
    }

    public string GetState()
    {
        return _state;
    }
}
Enter fullscreen mode Exit fullscreen mode

In this example, the Memento class has a constructor to initialize its state and a GetState() method to retrieve the saved state.

Finally, the Caretaker is responsible for storing and managing multiple mementos. It can stack the mementos or maintain a history of mementos for undo/redo functionality. Let's consider the Caretaker class:

public class Caretaker
{
    private Stack<Memento> _mementos = new Stack<Memento>();

    public void SaveMemento(Memento memento)
    {
        _mementos.Push(memento);
    }

    public Memento GetLastMemento()
    {
        if (_mementos.Count > 0)
            return _mementos.Pop();

        return null;
    }
}
Enter fullscreen mode Exit fullscreen mode

In this example, the Caretaker class uses a stack to store the mementos. We have methods to save a memento and retrieve the last saved memento.

Now, let's see how we can use these components together:

class Program
{
    static void Main(string[] args)
    {
        TextEditor editor = new TextEditor();
        Caretaker caretaker = new Caretaker();

        editor.Text = "Hello, World!";
        caretaker.SaveMemento(editor.CreateMemento());

        editor.Text = "Hello, Design Patterns!";
        caretaker.SaveMemento(editor.CreateMemento());

        editor.Text = "Hello, C#!";

        editor.RestoreMemento(caretaker.GetLastMemento());
        Console.WriteLine(editor.Text);  // Output: Hello, Design Patterns!

        editor.RestoreMemento(caretaker.GetLastMemento());
        Console.WriteLine(editor.Text);  // Output: Hello, World!
    }
}
Enter fullscreen mode Exit fullscreen mode

In this example, we create a TextEditor object and a Caretaker object. We set the editor's text, save the memento using the caretaker, change the text, and then restore the previous state from the memento using the caretaker.

The Memento Pattern allows us to easily save and restore an object's state without exposing its internal structure. It promotes the principle of encapsulation and enhances the reusability and flexibility of the code.

Top comments (0)