You can see this and other great articles on design patterns here.

The Memento Design Pattern allows you to save historical states of an object and restore the object back from the historical states. As your application is progressing, you may want to save checkpoints in your application and restore back to those checkpoints later. An example are the checkpoints saved in a video game where the user is allowed to go back to the stages that they have already conquered. Another example are the undo operations in a word processing application.

Let’s look at the UML of the memento pattern first, then we will look at some code to see how it works. Below is the UMLof the Memento Design Pattern:

  • The Originator class is the objects that will be saved and restored later:
    • The state variable contains information that represents the state of the Originator object. This is the variable that we save and restore.
    • The CreateMemento method is used to save the state of the Originator. It creates a Memento object by saving the state variable into the Memento object and return it. This is for recording the state of the Originator.
    • The SetMemento method restores the Originator by accepting a Memento object, unpackage it, and sets its state variable using the state variable from the Memento. This is for restoring the state of the Originator using the information that was previously saved in the Memento.
  • The Memento class stores the historical information of the Originator. The information is stored in its state variable.
  • The Caretaker class manages the list of Memento. This is the class for the client code to access.

The key to the Memento Design Pattern is that the client code will never access the Memento object, all of the interactions are done through the Caretaker class. The client code does not need to be concerned about how the states are stored and retrieved.

Below are the implementation code and the output of the Memento Design Pattern. It shows that we can save the states of the Originator and restore it back at a later point in time. Notice that the client code does not need to access the Memento objects:

				class Program
{
    static void Main(string[] args)
    {
        Originator<string> orig = new Originator<string>();

        orig.SetState("state0");
        Caretaker<string>.SaveState(orig); //save state of the originator
        orig.ShowState();

        orig.SetState("state1");
        Caretaker<string>.SaveState(orig); //save state of the originator
        orig.ShowState();

        orig.SetState("state2");
        Caretaker<string>.SaveState(orig); //save state of the originator
        orig.ShowState();

        //restore state of the originator
        Caretaker<string>.RestoreState(orig, 0);
        orig.ShowState();  //shows state0
    }
}

//object that stores the historical state
public class Memento<t>
{
    private T state;

    public T GetState()
    {
        return state;
    }

    public void SetState(T state)
    {
        this.state = state;
    }
}

//the object that we want to save and restore, such as a check point in an application
public class Originator<t>
{
    private T state;

    //for saving the state
    public Memento<t> CreateMemento()
    {
        Memento<t> m = new Memento<t>();
        m.SetState(state);
        return m;
    }

    //for restoring the state
    public void SetMemento(Memento<t> m)
    {
        state = m.GetState();
    }

    //change the state of the Originator
    public void SetState(T state)
    {
        this.state = state;
    }

    //show the state of the Originator
    public void ShowState()
    {
        Console.WriteLine(state.ToString());
    }
}

//object for the client to access
public static class Caretaker<t>
{
    //list of states saved
    private static List<memento><t>> mementoList = new List<memento><t>>();

    //save state of the originator
    public static void SaveState(Originator<t> orig)
    {
        mementoList.Add(orig.CreateMemento());
    }

    //restore state of the originator
    public static void RestoreState(Originator<t> orig, int stateNumber)
    {
        orig.SetMemento(mementoList[stateNumber]);
    }
}

Liked this article? You can see this and other great articles on design patterns here.

推荐.NET配套的通用数据层ORM框架:CYQ.Data 通用数据层框架
新浪微博粉丝精灵,刷粉丝、刷评论、刷转发、企业商家微博营销必备工具"