Memento Design Pattern
Without violating encapsulation, capture and externalize an object's internal state so that the object can be restored to this state later. (dofactory)
- Memento stores internal state of the Originator object. The memento may store as much or as little of the originator's internal state as necessary at its originator's discretion. Mementos protect against access by objects of other than the originator. Mementos have effectively two interfaces. Caretaker sees a narrow interface to the Memento -- it can only pass the memento to the other objects. Originator, in contrast, sees a wide interface, one that lets it access all the data necessary to restore itself to its previous state. Ideally, only the originator that produces the memento would be permitted to access the memento's internal state.
- Originator creates a memento containing a snapshot of its current internal state and uses the memento to restore its internal state.
- Caretaker is responsible for the memento's safekeeping and never operates on or examines the contents of a memento.
- The memento pattern is used when a snapshot of an object's state must be captured so that it can be restored to that state later and in situations where explicitly passing the state of the object would violate encapsulation (e.g. “undo” or “rollback” operations).
- Database transaction: consider an object representing a database table, a transaction manager object which is responsible of performing transactions must perform operations on the table object while having the ability to undo the operation if it fails, or if any operation on any other table object fails. To be able to rollback, the transaction manager object would ask the table object for a memento before performing an operation and thus in case of failure, the memento object would be used to restore the table to its previous state.
- Promote undo or rollback to full object status.
- An unlimited “undo” and “redo” capability can be readily implemented with a stack of Command objects and a stack of Memento objects.
- Using serialization along with this pattern, it's easy to preserve the object state and bring it back later on.
- Using the memento pattern can be expensive depending on the amount of state information that has to be stored inside the memento object.
- The caretaker must contain additional logic to be able to manage mementos.
- Saving or restoring of state can be a time consuming process.
- Used incorrectly, it can expose the internal structure of your object, thus allowing any other object to change the state of your object.
- Command and Memento act as magic tokens to be passed around and invoked at a later time. In Command, the token represents a request; in Memento, it represents the internal state of an object at a particular time. Polymorphism is important to Command, but not to Memento because its interface is so narrow that a memento can only be passed as a value.
- Command can use Memento to maintain the state required for an undo operation.
- Memento is often used in conjunction with Iterator. An Iterator can use a Memento to capture the state of an iteration. The Iterator stores the Memento internally.