MEMENTO DESIGN PATTERN

❉ Memento is one of the behavioral design patterns that is usually utilized for saving and restoring the state of an object into a previous state without violating encapsulation.

❉ It is also referred to as Snapshot pattern or Token.

❉ Memento pattern is used to carry out the functionality of undo/ rollback/revert operation. This will be very much useful when errors and failures occur.

Ref: https://refactoring.guru/design-patterns/memento

❉ Memento design pattern consists of 3 main design components that are also known as pillars.

💠 Originator

► Originator is the object that we need in order to maintain the state.

It is capable of saving itself.

► Memento object that captures the Originator’s state will be created by originator.

► Values of Memento objects will be set and get by the originator.

💠 Care Taker

► This is an object that keeps track of the originator and restores the state of the object from Memento.

►It is aware of why and when the Originator must save and restore itself.

► Although Memento is clearly visible to the caretaker, it should not operate on that.

► It should take a snapshot of the Originator and then operate on it.

► Care Taker has the ability to rollback and maintain the created Memento objects’ history.

💠 Memento

► This can be known as a lock box that includes and restores the internal state containing any number of state variables of an object.

► Memento object is immutable that permits to restore the internal state of the originator.

► A memento contains 2 interfaces namely;

  1. CareTaker
  2. Originator

❉ When we implement this Memento design pattern, Originator couples with Memento and pass state into CareTaker. Whenever we need to go to the previous state, we need to talk to CareTaker, check the previous state and move.

UML of Memento Design Pattern

Ref: https://images.app.goo.gl/tZ6roQaM1gNr6Ffe9

Usage of Memento Design Pattern

📍 Utilized in database transactions

📍 Used in applications that needs to save the last work done when restarting.

Real World Use case to explain Memento Design Pattern

Assume there is an application that is used to design Graphical User Interfaces called “iDesign”. When a user designs a GUI, it must show the list of elements (i.e Frames, Labels, Text Boxes, Buttons, Sliders, Panels etc.) in a Palette that are used to design that particular GUI. Sometimes, we will need to go back and undo the GUI design into a previous state. In some cases, the user will need to add new elements after reverting back the process.

Let us implement this process using Memento Design Pattern.

💫 Element Class

💫 Palette Class

🍁 In collection framework, assume you add objects to a list and if you assign one list to another list directly. If you modify the second list later, the original list too will get changes because you have copied references.

🍁 To avoid that happening, Clone() method is used.

🍁 An ArrayList is defined rather than a List, because we need to use clone() method.

🍁 getElement() method of the ArrayList is marked private because the Palette class will only have the access to it.

💫 CareTaker Class

🍁 This is the class that holds the state of the previous object.

🍁 Let us say you get one element and save it. And then you get another element and save. But, when you undo, you need to give first state first.(LIFO — Last In First Out)

🍁 Therefore, it needs to be implemented as a Stack.

🍁 The state of the Palette must be given to CareTaker.

Let us move to application class.

Now lets assume we gave the feature to save the palette state. Lets say user add first 2 elements and save the palette. After that, user does this to every element he adds.

OUTPUT

You can see that First time, you have two elements because we save the palette after adding two elements.

How this works is, you create a palette and you put this entire palette on CareTaker. That is kind of a version of the palette. You have to keep in mind not to confuse this with the elements inside the palette.

Let us revert this now.

You can see the same palette is repeating as follows.

Let us revert few more times.

OUTPUT

We get slider 2 times because, we added slider to the palette. And gave that palette to the caretaker. When we ask the CareTaker to revert, it will give the palette what you gave last. (same palette that you have in hand right now)

Now, Lets stop giving slider to the CareTaker and run this program.

OUTPUT

Now you will not get the Slider twice. Now, the CareTaker has the palette which has the Button. CareTaker and the user have two different versions.

Let us add one more element to the palette, that is a Panel and implement this.

💫 Application Class

OUTPUT

Advantages of Memento Design Pattern

♻️ Originator is simplified.

♻️ This pattern gives a technique for recovery that is easy to be done.

♻️ Preservation of encapsulation boundaries.

♻️ Encapsulation related to key objects in this model is not guaranteed.

♻️ High cohesion is maintained well.

Disadvantages of Memento Design Pattern

♨️ Lot of storage will be needed by a high number of mementos. And this will set down the caretaker with additional burdens.

♨️ It will consume lots of time in the process of saving states that will lead to performance issues.

♨️ High maintenance costs due to utilization of codes used to manage memento classes.

Facts to Remember ‼️

🔔 Memento acts like magic tokens that can be invoked later once passed around.

Real World Examples for Memento Design Pattern

🔶 Finite State Machines

🔶 Git stashing

🔶 javax.swing.text.JTextComponent — Undo support mechanism will be provided by this class.

🔶 javax.swing.undo.UndoManager — Acts as a caretaker

🔶 javax.swing.undo.UndoableEdit — Acts as memento

🔶 javax.swing.text.Document — Acts as originator

References