An Introduction to Memento Design Pattern

Hasini Sandunika Silva
CodeX
Published in
4 min readMay 26, 2021
An Introduction to Memento Design Pattern

The memento design pattern allows to undo or restore the previous version of the object. This is categorized under the behavioral pattern. As per the book written by the gang of four (GOF), there are 3 pillars in the memento pattern called originator, memento, and the caretaker.

  1. Originator: This creates the memento object and this is the original object that the state needs to be saved.
  2. Memento: This is responsible for storing the internal state of the originator.
  3. Caretaker: This keeps track of the mementos.

Let’s understand this using a real-world scenario.

Assume, a certain company provides rewards to their employees based on their seniority level and the performance index. There are 3 seniority levels named 1, 2, and 3. One is the highest level and 3 is the lowest seniority level. The performance index also follows the same order. The rewards are offered for the employees who hold both seniority level and performance index less than or equal to 2. Here, HR can add rewards to the employees and they can revert the added rewards if the corresponding employee shows less performance.

To implement this scenario,

First, I have created a class called EmployeeReward to hold the information about the records of the rewards of employees. Apart from that, I have created another class called Constants to hold the constant values that will be used during the implementation. Refer to the following codes.

Next, I have created another class called RewardHandler and added a method called addReward(EmployeeReward employeeReward) to add the rewards of the employees to an ArrayList. A reward is added when the employee’s seniority level and performance index is less than or equal to 2. Here I have implemented a method called getRewards() to return a cloned object of employeeRewards ArrayList. Inside the RewardHandler, I have declared a static class called RewardHandlerMemento. Again inside the RewardHandler, I have created a method called saveReward() to return an instance of RewardHandlerMemento by passing the parameter of the cloned ArrayList (using getRewards() method). Here, I have implemented a method called revertReward(RewardHandlerMemento rewardHandlerMemento) to set the reference of the ArrayList of the instance of RewardHandlerMemento to the ArrayList of the RewardHandler class. Apart from that, I have overridden the toString() method to display the details inside the RewardHandler class. Refer to the following code.

Here, the EmployeeReward class is considered as the originator and the RewardHandlerMemento class is considered as the memento.

Next, I have implemented a class called RewardHistory to keep track of the instances of RewardHandlerMemento. Here, I have created a stack to track the instances created from the RewardHandlerMemento class and this is done by the saveReward(RewardHandler rewardHandler) method. After that, I have implemented another method called revertReward(RewardHandler rewardHandler) to return the top element of the stack and assign the reward of that returned instance of RewardHandlerMemento to the ArrayList declared inside the RewardHandler class. Refer to the following code.

This is considered as the caretaker.

Finally, I have implemented the main method inside the MainApplication class. Refer to the following code.

Here, first, I have added 3 rewards to the ArrayList declared inside the RewardHandler class and saved the mementos of that to the stack. After that, I have restored the final action by calling the revertReward(RewardHandler rewardHandler) method of RewardHistory class. The following defines the output received.

Sorry, Employee with name: Hasini and ID: 003 cannot get rewards
Employee ID: 001
Employee Name: Hasini
Employee's Performance Index: 2
Employee's Level: 2
Employee's Reward Type: Dinner
Place: Marina Bay
Employee ID: 002
Employee Name: Sandunika
Employee's Performance Index: 1
Employee's Level: 2
Employee's Reward Type: Tour
Place: India
_____________________________Employee ID: 001
Employee Name: Hasini
Employee's Performance Index: 2
Employee's Level: 2
Employee's Reward Type: Dinner
Place: Marina Bay
Employee ID: 002
Employee Name: Sandunika
Employee's Performance Index: 1
Employee's Level: 2
Employee's Reward Type: Tour
Place: India
_____________________________

As per this, when calling the revertReward(RewardHandler rewardHandler) method of RewardHistory class, the returned instance of RewardHandlerMemento class (top element of the stack inside the RewardHistory) is caught by the revertReward(RewardHandlerMemento rewardHandlerMemento) method in RewardHandler. After that, the reference of the rewards of RewardHandlerMemento is assigned to the employeeReward inside the RewardHandler. So, this is used by the toString() method in RewardHandler class, and this is caused to give the same output even after calling the revertReward(RewardHandler rewardHandler) method inside the main method.

To avoid this, the entity we want to undo should not be saved to the stack. Because of this, no new instance of RewardHandlerMemento is gone into the stack and no revert for that. Refer to the following code.

The following defines the output received.

Sorry, Employee with name: Hasini and ID: 003 cannot get rewards
Employee ID: 001
Employee Name: Hasini
Employee's Performance Index: 2
Employee's Level: 2
Employee's Reward Type: Dinner
Place: Marina Bay
Employee ID: 002
Employee Name: Sandunika
Employee's Performance Index: 1
Employee's Level: 2
Employee's Reward Type: Tour
Place: India
Employee ID: 004
Employee Name: Hasini
Employee's Performance Index: 1
Employee's Level: 1
Employee's Reward Type: Tour
Place: UK
_____________________________Employee ID: 001
Employee Name: Hasini
Employee's Performance Index: 2
Employee's Level: 2
Employee's Reward Type: Dinner
Place: Marina Bay
Employee ID: 002
Employee Name: Sandunika
Employee's Performance Index: 1
Employee's Level: 2
Employee's Reward Type: Tour
Place: India
_____________________________

This is the end of the article. I hope you have got some understanding about the Memento pattern. Let’s meet in another article. Till then, stay safe!!😍😍

References

--

--