Memento falls under the behavioral design pattern category. The purpose of
memento design pattern is to record the internal state of an object. Recording
of an object’s internal state can also be referred to placing checkpoint at
different level of program execution. The checkpoints are later used in case of
undo or any unexpected operation (e.g. crash) by the program to retrieve the
state of an object. Memento should not be mistaken with command pattern. Command
pattern can use mementos to maintain state for undoable operations and mementos
can be used by iterators.
Problem
In order to save an object’s internal state, state must be saved somewhere.
Saving an object’s internal state externally is not easy as object may or may
not encapsulate all the data. Therefore, making it inaccessible to objects
outside to save their state.
Solution
Memento comes to rescue by storing a snapshot of internal state of another
object. The object that stores the internal state is called Memento and
the object of which internal state is saved is called originator. The memento
pattern also utilizes a Caretaker class. This is the object that is
responsible for storing and restoring the originator's state via a Memento
object.
But it is originator that initializes memento with its internal state. A memento
is opaque to an originator and to its caretaker.
Example
Let’s consider a Rectangle which is drawn on a canvas. Its position is initially
fixed but can be changed on canvas either by dragging or changing its x, y
coordinates in the toolbar. The operation can be undone by clicking undo button.
The idea is simple as explained above. We need to save the internal state of
rectangle in a memento when coordinates are changed. When undo is performed, we
use memento to reset rectangle; the originator. The example can be extended to
perform multiple undo operations. But in my example, for the simplicity I have
permitted only 1 undo operation. However, with the help of iterators, multiple
undo operations can be implemented also.
As said, the Memento is opaque to other classes; the class can typically be a
private inner class of the Originator. Therefore, the Originator will have
access to the fields of the memento, but outside classes will not have access to
these fields. This means that internal state information can be transferred
between the originator and the memento within the Originator class, but outside
classes do not have access to the state data stored in the Memento.
As memento is either an inner class or private class, caretaker will have only
reference to memento. In other words, caretaker is a safe-keeper of a
checkpoint; the memento. At later point, when needed, caretaker can use the
reference and instruct the originator to reset its state with respect to
memento.
So as to summarize, memento shields encapsulation and does not let originator
expose its internal state and implementation. It also supports single
responsibility principle by helping originator not to keep track of its previous
state since this is the responsibility of the caretaker.
However, using the memento pattern can be expensive depending on the amount of
state information that has to be stored inside the memento object. In addition,
the caretaker must contain additional logic to be able to manage mementos.