June 11th 2020
Memento design pattern is a software design pattern that is used to roll back an object to its previous state. It is a part of the behavioural design pattern which is concerned with algorithms and assignment of responsibilities between objects.
Behavioural patterns describe patterns o deal with communication between objects or classes. Memento Design Pattern has much applicability when it comes to restoring the state of an object. Applications that need users to fall back to a previous state make use of the memento design pattern.
The intent of this design pattern is to not violate the encapsulation principle by not exposing information outside the desired objects. In this article we will discuss scenarios where we can use the memento design pattern, describe what is the memento design pattern, talk about its benefits and drawbacks as well. Let us get started
What is the memento design pattern?
The memento design pattern’s intent is to externalize an object’s internal state so that the object can be restored to that state later without violating the encapsulation principle. Game applications need to maintain snapshots of the levels the player has played. As the user progresses to different levels in a game, chances of encountering a game-ending situation increases.
Most games allow users to restart the game from the previous level. The ideas of memento design pattern are being used in most of the circumstances when it comes to storing and restoring state in games.
Another example can be drawn from a drawing application like paint in Microsoft’s Windows operating system or any other graphical editor that supports connecting objects. We can create two circles and join them using a line. Now, if we move the system of rectangles by either selecting the whole figure or by any other means, the rectangles should stay connected.
The graphic editor makes sure that the line stretches appropriately to maintain the connection between the rectangles. If we are trying to create a graphic editor of our own, we can use the memento design pattern to ensure that the desired effect is achieved. Such applications make use of an object that calculates the length, position, and angle using mathematical equations.
That object takes the help of the memento design pattern’s toolbox objects to store the previous constraints (length, position, angle). So that, if the user moves the rectangular system next time the previous state can be used to determine the next position.
The memento design pattern consists of an object that stores a snapshot of the internal state of another object, which is the memento’s originator. The mechanism for undo requests a memento from the originator when it needs the list of checkpoints from the originator’s state. The originator is the one that initializes the memento with information that characterizes its current state.
The restriction is that the originator is the only one that stores and retrieves the information from the memento. Let us look at these participants one by one to get a clear understanding of what all these mean –
The memento object stores the internal state of the Originator object.
The originator has access to the memento object and any other object does not directly interact with it.
The originator itself is responsible for creating a memento that contains the snapshot of its current internal state.
Also, it uses the memento to restore the internal state
The caretaker class is responsible for safekeeping memento’s snapshot of states. It maintains a list of state that is then used by the originator to switch back to. You will understand the usage of this class with the help of an example of the memento design pattern.
Memento Design Pattern Example
The memento class consists of the state variable, in our case we have used a plain string to represent the state. Memento class has got two methods; one is the constructor and the returns the current state.
Fig: memento design pattern example in java
Memento keeps a single snapshot that is then maintained as a list by the caretaker object
The originator is responsible to set the state of the object and it uses the setState() method to do so. The saveStateToMemento method returns a new Memento object with the current state stored in it which is stored in the CareTaker object’s memento list.
And getStateFromMemento returns the current snapshot of the state.
Fig: memento design pattern example in java – Originator originates the state
The caretaker class maintains a list of snapshots of the states in the form of memento objects. It is from the caretaker object that we can jump into different states we stored because it is the one containing the complete list. The get method returns snapshot using the index passed on to it.
Fig: memento design pattern example in java – CareTaker maintains a list of state
4. Memento Pattern Demo
As you can see, the originator object is setting the state and the snapshots of the memento object are being added to the list maintained by the caretake object. In order to get the current level, we can make use of the getState() method from the originator object directly. However, the caretaker object is the one from which we can get the snapshots of the state and reflect it upon the originator class.
The getStateFromMemento() method gets the “level” (state) which we want to jump in and sets it to the state variable of the Originator object. Now, if we use the getState() method directly from it, we can see that we have restored a previously saved state from the list maintained by the caretaker object.
Fig: memento design pattern example in java – Memento Pattern In action
What are the pros and cons of using the memento design pattern?
- Memento preserves the boundaries if encapsulation by avoiding exposing information that only an originator should manage. However, that should be stored outside the originator, as we saw in our code example. We stored that in the caretaker object.
- The memento design pattern allows us to keep our code simple on the client-side by letting the caretaker maintain the list of states.
- Keeping the saved state external from the key object helps maintain cohesion.
- It provides an easy way to implement recovery/ undo features for an application.
- Mementos might cause heavy use of memory if the originator has to copy a large amount of information to store in the memento.
The Memento design pattern has two goals:
- One is to save the important state of a system’s key object.
- The other is to maintain the key object’s encapsulation.
The Memento Design Pattern promotes the single responsibility principle by providing an option to keep the state we are saving separate from the key object. And that separate object as we saw is the Memento Object. However, the list of snapshots of the state is maintained by the caretaker object and not the memento.