Introduction to Memento pattern

Hasitha Subhashana
3 min readJun 7, 2021
Source: https://9gag.com/

At least once in our life, we wish, if we had an undo button. But unfortunately, there is no undo. But you cant say the same about software engineering. Because we software engineers have the Memento design pattern which is a Behavioral pattern.

You can use the Memento pattern, whenever you want to get a previous state of an object. Think of scenarios like, when the user requests to undo the list of items in a shopping cart or when you want to undo the changes to the text in a notepad or whenever a pc gamer wants to open the game in a previously saved state as in GTA - Vice City.

Source: https://logolasopa475.weebly.com/

To implement Memento we need the following in our code.

  • Originator: save its state in the Memento object and store the states from the Memento object when necessary.
  • Caretaker: Keep track of originators history using a Stack.
  • Memento: contains the state of an object.

How the implementation works are, Originator works with Momento and passes the state into the caretaker. So whenever we want to roll back, we take the previous state from the caretaker

Example for UML class and sequence diagram of the Memento pattern (Source: https://en.wikipedia.org/)

Now let's try to implement a similar scenario to a game progress saving.

We have a game like “Super Mario” and the player wants to save progress and sometimes the player wants to undo the progress to a previous level.

First, let's implement a class to store details of the player’s current level. This class can store the current level. Also, it has a constructor to add a level whenever the player progress through the game.

Next, let's implement a game progress class and have an ArrayList to store game levels and a method to add levels to this ArrayList.

We still have to implement the CatreTaker and other methods. But let's see if our application works for now. Let's go ahead and create a class with main() method to add game levels to the ArrayList created.

Output:

Game level:[Level number :LEVEL-1]
Game level:[Level number :LEVEL-1, Level number :LEVEL-2]

Well, so far it's working fine. But still, we cannot save the status or undo it to a previous status, so let's update our GameProgress class with methods to save the status and roll back to previous changes.

Next, implement the CareTaker class to keep track of changes. A Stack is used to store the changes.

Now that it's done let's update the Application class to save and undo. I'm using saveProgress() method to save the state and undoProgress() method to undo changes to the previous state.

Game level:[Level number :LEVEL-1]
Game level:[Level number :LEVEL-1, Level number :LEVEL-2]
Game level:[Level number :LEVEL-1]

Here I have added “LEVEL-1” and then saved it. Then I have added “LEVEL-2”, but haven’t saved it. Because if I save it, then it becomes the current state. If you save it don't forget to undo it twice. (Look below for an example).

Game level:[Level number :LEVEL-1]
Game level:[Level number :LEVEL-1, Level number :LEVEL-2]
Game level:[Level number :LEVEL-1]

If you didn't undo twice, you will probably get the same output again.

Game level:[Level number :LEVEL-1]
Game level:[Level number :LEVEL-1, Level number :LEVEL-2]
Game level:[Level number :LEVEL-1, Level number :LEVEL-2]

So if you want to have a look at the code I have saved it here in my Github repo. Most importantly make the right choice in your life. Because there is no going back.

References

--

--