Memento | Cheat Sheet
Behavioral Pattern — Design Patterns Series
Mementos are very important when you need to store and restore a long history of complex object structures. This includes, for example, undoing or redoing drawings (e.g. in Photoshop or in CAD systems), music compositions (e.g. using Cubase), or videos (e.g. in Sony Vegas).
Real-life examples
- Volume control on the TV: You set a certain volume and then switch to “muted” mode. After leaving this mode, you end up at the previously set volume.
- Any GUI editor with undo or redo commands (Photoshop, text editors, …)
- Calculator
- Database transaction: if a transaction with all its operations fails, it can be rolled back easily
Meaning
- Capturing and externalising the internal state of an object without affecting its capsules
- Objects can be returned to a different state from a later point
Applicability (suitable if …)
- The state of an object (or a part of it) needs to be saved, so it can be restored at a later stage
- A direct interface to retrieve the state would reveal implementation details and compromise the object’s capsules
Assets and Drawbacks
- Maintaining encapsulation boundaries — avoiding the release of information to the outside world
- Simplification of the originator — the burden of memory management is on the originator and one thus has information control
- The use of mementos can be laborious (when copying large amounts of information)
- Hidden effort in managing mementos at CareTaker (e.g. large memory management load when saving mementos)
Example
In the following example I backup the current style and its descriptions of an Angular Material card. First of all, we need an interface and a concrete class for this. To use Dependency Inversion at a later stage, you need an interface for the card:
After this, you can create the Memento class to store the internal state of a MatCard. Additionally, you can add a date to ensure the right edit order:
Afterwards, you need an Originator which is responsible for state handling. It creates a Memento that contains a snapshot of its current internal state. With this, different states can be restored, too:
The Caretaker is responsible for safekeeping the Memento and does not change or access the content of the Memento:
Now you can create different MatCards from outside or from another class, restore them, and output their history:
Conclusion
Design Patterns are an important resource and base knowledge for every developer — they are very helpful for solving programmatic problems, help with consistent communication with other developers about system design, and serve as a significant introduction into object composition (besides inheritance) and dependency inversion.
Behavioral Patterns deal with algorithms and assignment of responsibilities to objects. Furthermore, they describe mutual communication patterns and grasp complex program sequences. They are therefore very well applicable in areas where complicated code needs to be made readable and maintainable. Extensions are, in consequence, very good and quickly implementable.