In this article, we will be discussing the Memento design pattern, which is part of behavioral design pattern. Memento design pattern is aimed at maintaining the state or values of an instance of a class. This state can be re-stored when required. It is like creating a check point or snapshot of data at a given time. In case any issue is encountered in the further process, then we can re-store the check point or snapshot data. In other words, it provides a ability to achieve the Undo type functionality.
So let’s discuss this pattern in detail now.
What is Memento pattern ?
According to GoF’s definition, this pattern is :
Without violating encapsulation, capture and externalize an object’s internal state so that the object can be restored to this state later.
A Real world example :
Let’s take an example of a computer game, where we have a player who will have to cross levels 1 to 5 to complete the game and will score different scores at each level. We will create a checkpoint for this player at level 1, with some initial score at a particular instance of time, and store a snapshot of its data. Then we will update the score, level and time of the player. Now with some business rule, say the player looses a life, he will again have to start from that checkpoint. So when he starts again from the checkpoint, we will restore the snapshot data and proceed further accordingly. In order to achieve this, we will divide the system into following components.
1. Originator or MainClass : This is the main class of the system which maintains the data of the player i.e. its level, score etc. and for which we want to create a snapshot of the data. In our case, it will be PlayerStatistics class, with 3 properties named Level, Score & CheckPointTime. These are the properties or the data of the player, for which we want to create a snapshot.
2. Memento : This class is used to store the snapshot of the Originator class data. In our case, it will be CheckPointMemento class, only with properties, for which we want to store the data i.e. for each of the property that we want to have in the snapshot, we create a property in the memento class.
3. CareTakerClass: This is like a container class, which holds the Memento class instance, which further holds the snapshot of the original data. In our case, it will be CheckPointCareTaker, and will hold the memento instance using a property defined in it.
So, to start with, we create following classes :
- A PlayerStatistics class and its properties.
- A CheckPointMemento class, with the properties for which we want to store the snapshot data of the PlayerStatistics class.
- A CheckPointCareTaker class, which will act as a container for CheckPointMemento class.
See the classes below. These are the memento and caretaker classes.
Now we will create the main class PlayerStatistics and an important point to note here is that the PlayerStatistics class will have two methods, apart from the properties to hold the player data. These methods are :
1. CreateCheckPoint() : This method will be used to return the instance of the memento, which is storing the data for which we would like to create a snapshot. The instance returned by this method will be added to the container or the CheckPointCareTaker class, by setting the property.
2. RestoreCheckPoint() : This method will receive the memento class instance or you can say the snapshot data which we added at the checkpoint. Data received will be then set back to the original properties.
See the complete code for the Main/originator class, with the properties and the two methods discussed above.
Now we have setup the initial code and its time to write the client code. So we start with setting some initial data for the player. Then we will store the data in a memento instance and add it to the caretaker container class. Further we will change the data and then finally retrieve the stored data from the memento instance. So our code will be like the following :
How is it working ?
Let’s discuss the client code now.
- In step 1, we simply set properties of the player data and print them.
- In step 2, we call the CreateCheckPoint() method in the main class, and generate the instance of the memento class type. This instance is then assigned to the CheckPointCareTaker class, which acts as a container here to hold the snapshot data.
- In step 3, we simply update the data and print it, like we did in step 1.
- In step 4, we basically perform the undo operation and retrieve the original data which we had at the start. This is done by calling RestoreCheckPoint method in main class and passing it the data from the container or caretaker class. The data receive is then set back to the properties and printed again.
So this was all about the memento design pattern. Hope you enjoyed reading it…!!!