Avijeet Dash, Satyabrata
Dash and Sunita R
Intent
Without violating encapsulation, captures and externalizes an object's
internal state so that the object can be stored to this state later.
In 30 Seconds
The catch here is "to store the private state information of an object
in the form of an object". A memento is an object that stores the snapshot
of the internal state of another object. The state information of an object is
required when we want to restore objects to their previous states while undo
operations. A memento is a "reminder" of how things were. It is an
alternate representation of another object, often in a format suitable for
transmission across an external interface. It can be thought of as a black box
that holds state, but is otherwise opaque to everything except the class that
creates it.
Motivation
Memento's intent is to capture and externalize an object's state so that the
object can be restored to that state at a later time.
There are 3 participants in this pattern.
Originator - whose state has to be maintained
Memento - stores the state of the Originator object
Caretaker - has a handle to the Memento
Externalizing the state must be done without violating the object's
encapsulation. i.e., the object's internal state should be available
but not visible to other objects.
For this, Memento gives the Originator a wide interface and the
Caretaker a narrow interface. Implementation of the wide interface varies
depending on the programming language. C++ allows the Originator to be a
friend of the Memento. Java permits a Memento to be an inner
class of the Originator
Sample Code
//This class state will be stored. public class Originator { private int number; private File file = null; // constructor public Originator(){ } // create a Memento public Memento getMemento(){ return new Memento(this); } // restore the state of the originator public void setMemento(Memento m){ number = m.number; file = m.file; } //state that can be used for read/write from/to disk private class Memento implements java.io.Serializable{ private int number; private File file = null; // private constructor - only the originator can create a Memento private Memento( Originator o){ number = o.number; file = o.file; } } }
Complexities simplified
Using mementos might be expensive
Mementos might incur considerable over-head if originator must copy large
amount of information to store in the memento or if the client create and return
mementos to the originator often enough. The originator in that case can take
care of storing its state to disk and managing the restoring activity.
The other solution is to store incremental changes in mementos. When mementos
get created and passed back to the originator in a predictable sequence, then
memento can save just the incremental changes to the originator’s internal
state.
Also Known as and Related Patterns
Commands can use mementos to maintain state for undoable operations. A
memento can be used with iterator to search collections for specific states.