Click here to Skip to main content
Click here to Skip to main content
Technical Blog

Memento Design Pattern

, 4 May 2011 CPOL
Rate this:
Please Sign up or sign in to vote.
Memento Design Pattern clearly explained with example

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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

DevLake

United States United States
No Biography provided

Comments and Discussions

 
GeneralMy vote of 4 [modified] PinprofessionalAmol_B2-Mar-14 22:54 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.1411023.1 | Last Updated 4 May 2011
Article Copyright 2011 by DevLake
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid