Memento Design Pattern

1.  Classification
2.  Intent
3.  Motivation
4.  Structure
5.  Consequences
6.  Sample Code
7.  Related Patterns
Classification  top
Memento is a behavioral design pattern.
 
Intent  top
1.  Capture an objectís state so that the object can be restored to that state later.  
2.  Externalize an objects state without violating encapsulation.
 
Motivation  top
For most applications it is important to allow the users to "undo" an operation or to return to a previous state.  For example, in Microsoft Word you are permitted to undo a delete operation.  Another example would be form processing in a web application.  If a client makes an error inputting information into the form, it is desirable to return the client to the form displaying the information inputted before submission.

This may be accomplished by creating a clone of the object, but this can be expensive.  Instead, we want to only store the relevant information (or memes) needed to perform the undo operation (i.e. make a "partial clone").
 
Structure  top
|---------------------------|              |--------------|
|      originator           |              |   memento    |          |-------------|
|---------------------------|              |--------------|          |caretaker    |
|-state                     |------------->|-state        |<-------<>|-------------|
|---------------------------|              |--------------|          |-my_memento  |
|+restore_memento(memento) o|              |+get_state    |          |-------------|
|+save_memento()   o       ||              |+set_state    |          |+get_memento |
|------------------|-------||              |--------------|          |+set_memento |
                   |       |-------.                                 |-------------|
                   |               |
                   |               |
                   |               |
 |-------------------------|      |---------------------|  
 |return new memento(state)|      |state = m.get_state()|
 |-------------------------|      |---------------------|
 

Descriptions of the objects in the above UML diagram:
Memento - This object stores the internal state of the Originator object.  It allows only the originator to access its internal information.

Originator - This object can create memento objects that store its internal state.  It can also restore its state from a Memento object.  The Originator's "save_memento" method creates a new Memento object and initializes it with the Originatorís internal state.  The Originatorís "restore_memento" method sets all of its internal variables to the ones recorded earlier in that Memento object.  Once this method is called, the Originator will behave exactly as it did before the Memento was recorded.

Caretaker
- This object stores the Memento objects of the Originator.  The Caretaker should not be able to explore the contents of, or operate on, a Memento object.  When an undo or similar operation is called, the Originator calls the "get_memento" method of the Caretaker and this returns the appropriate Memento object as a parameter to the Originator's "restore_memento" method..

 
Consequences  top
Benefits
  • It eliminates the need for multiple creation (cloning) of the same object (i.e. Originator) for the sole purpose of saving its state. Since a scaled down version of the Originator is saved instead of the full Originator object, space is saved.
  • It simplifies the Originator since the responsibility of managing Memento storage is no longer centralized at the Originator but rather distributed among the Caretakers (Gamma et al, 1995).
Drawbacks
  • The Memento object must provide two types of interfaces: a narrow interface to the Caretaker and a wide interface to the Originator. That is, it must acts like a black box to everything except for the class that created it.
  • Using Mementos might be expensive if the Originator must store a large portion of its state information in the Memento or if the Caretakers constantly request and return the Mementos to the Originator.
 
Sample Code  top
I wrote a simple java implementation of this design pattern.  You can download the files by clicking on the links below.  After you have downloaded all of the files, compile and run the memento_driver.java file.  Each file is fully commented.

memento_driver.java
originator.java
caretaker.java
memento.java

Related Patterns  top
Command - The command can use the Memento design pattern to implement it's undo facility.  In this case the Command object would be the Originator (see UML above).  When executing itself, the Command first calls the "save_memento" method provided by the Originator to obtain a Memento of the Originatorís current state, then the actual operation is carried out.  If later the operation needs to be undone, the command calls the "get_memento" method of the Caretaker to pass to the Originator the previously saved Memento.

Singleton - In the above case (where Commands are used as Caretakers) it is useful to make the Command a Singleton object.  This will provide a global point of access for other objects to the Caretaker.

Iterator - A Memento object can be used in conjunction with Iterator to capture the state of an Iterator at some point ("Cursor").