Momento pattern
Definition
Without violating encapsulation, capture and externalize an object’s internal state so that the object can be restored to this state later.
Introduction
Consider a computer game that goes on for a long time. In a well-designed game, it is necessary to keep saving the state of the game periodically. This will allow a player to undo a wrong move or revert back to an earlier level and resume playing. You may be thinking that this is possible without applying any design pattern by implementing the logic to undo and revert back in the core applications itself. But, as I mentioned earlier, we are working on a well-designed game where the object’s internal states are not exposed because by doing so would violate encapsulation – a key OOP concept.
Besides gaming applications, such requirements and challenges are also part of other types of applications. For example, a desktop word processing application should allow users undo their operation while an enterprise e-commerce application might require allowing a user to revert back a checkout process comprising of multiple steps to an earlier step. The Memento Pattern is there to address such requirements without violating encapsulation.
When using the Memento Pattern, you have an object, called the Originator whose state (or even its partial state) needs to be saved. You then create another object, called the Memento which will hold different states of the Originator. Therefore the Memento class needs to have the same properties as the Originator in order to save the state. But if the Originator has its properties as private fields, then they won’t be accessible outside the Originator. This means the Memento object cannot access the private fields? The solution to this problem is the is core to the Memento Pattern. By applying the Memento Pattern, the Originator object will be able to:
- Create a Memento object with the current state of the Originator object. The Originator will update the Memento object whenever it’s state changes and it deems it necessary to save the changed state.
- Restore its previous state from a Memento object. By separating the logic of saving an object state from the object (Originator) itself, the Memento pattern adheres to the Single Responsibility principle, one of the SOLID design principles.
The Memento itself is a POJO that remains “opaque” to other objects. It is only the Originator that can store and retrieve state information from the Memento.
We have an Originator object that will create different Memento objects to hold it’s current state as it’s state changes. But how will you manage the Memento objects? This is where the Caretaker object comes into play. The purpose of the Caretaker object is the safekeeping of Memento objects. It is equally important that the Caretaker object never modifies the state of the Memento object. This modification would ripple back to the Originator object, and would be a violation of encapsulation.
Participants
Consider an employee management application which a user of the HR department uses to enter employee details when a new employee joins. The process is long and divided into multiple steps. It starts with storing basic information of the employee, and continues to recording previous working history of the employee. Imagine, if the user makes an error during the process and finds it in the last step of the process. It would be a poor user experience to force the user to start over. We need to allow the user to undo the steps and work backward to correct the error.
By applying the Memento pattern, we will create a EmpOriginator class, which is object we wish to save the state of. We will then create an EmpMemento class which will represent the different states of the EmpOriginator object. Finally, we will create the EmpCaretaker class which will manage the EmpMemento objects.
In summary, there are the objects we will be creating to implement the Memento Pattern:
- Originator (EmpOriginator): Is a class the state of whose object needs to be saved. It creates a Memento containing a snapshot of its current state. Originator uses the Memento to restore back its state.
- Memento (EmpMemento): Is a class whose objects stores states of the Originator. Memento denies other objects access to itself except the Originator.
- Caretaker (EmpCaretaker): Manages and safeguards Memento.
Memento Pattern in the Spring Framework
We can see the Memento Pattern in use within the Spring Framework in Spring Web Flow. Spring Web Flow is a Spring project which is used in conjunction with Spring MVC to build complex web flows (a series of tasks, like a loan application). Clearly, this is an ideal use case for the Memento pattern. Spring Web Flow implements the Memento Pattern through StateManageableMessageContext interface. Through the use of this interface, you can use Spring Web Flow to restore the application back to a previous state.
Summary
The Memento Pattern is a powerful design pattern, which should be in your programming toolbox. A common usage of this pattern is an implementation of ‘Ok’ and ‘Cancel’ dialogs. When the dialog loads, its state is stored and you work on the dialog. If you press Cancel, the initial state of the dialog is restored.
The Memento pattern is also used as a solution for thread safety problem in service classes. To avoid concurrent access problems in singleton services classes that have state, the Memento pattern is used to externalize the state into a Memento class, thereby making the service class stateless.