Memento Design Pattern
Image generated using Microsoft Designer

Memento Design Pattern

Memento design pattern is used to save the state of an object at any point of time and then later go back to the older state when required. This makes it very useful to support operations like undo, redo, backup and restore etc.

Problem

Let's try to understand this pattern with the help of a calculator application. Consider that you are working on a calculator and you want to support undo and redo operations in your application. There are two possible ways to implement these operations:

  1. Recalculate the previous/next state.
  2. Save the previous/next state and restore to it later.

1. comes with certain performance challenges associated with recalculating the states everytime along with some implementation challenges with functions like modulus (%) being completely one way.

In order to save the state as in 2. we want our objects to have all their content with public access. This is a big caviet. Even then if we directly save/restore state from our Client code, any changes in the state would require changes in this code. This tightly couples the client code with the state.

Solution

Zero points for guessing. The solution for this problem is the memento pattern.

Like we saw earlier saving the state of any object from outside requires us to make the member variables public. Memento pattern gives the responsibility of saving it's state to the originator object itself. Thus, instead of other objects trying to copy this state from outside, our champ does it himself. This saved state is referred to as memento. Other objects may only interact with memento with a limitied interface and can only access metadata like creation time, size, operation name etc.

We create another class called the caretaker class. The caretaker is responsible for storing the mementos. As mentioned above the caretaker can only access limited information about the memento. When restoration is required the caretaker passes this memento to the originator class which then restores the data.

Let's now look at the implementation. This implementation makes use of nested classes, available in languages like C++, C#, Java etc. For languages where nesting classes is not possible there is another way which we'll look into some other day.

Implementation

Originator and Memento Class

No alt text provided for this image
Code snippet showing Originator and memento class. (Please also read the comments)

Caretaker Class

No alt text provided for this image
Code snippet showing Caretaker Class. (Please also read the comments)

Client Class

No alt text provided for this image
Code snippet showing Client Class. (Please also read the comments)

Code Explaination

We have a Calculate Class which containes the logic of the calculator. Inside this class is the nested Memento Class. Our Calculate class has the responsibility to save and restore it's own contents.

We also have a caretaker class called the HistoryStack. In our case, the HistoryStack contains a Stack of Object class and not Memento class because Memento class is a nested class and only the objects of it's super class (Calculate) can access it. All classes in Java extend the Object class. Since Object is a parent of all classes it can be used to reference any class. In place of Object we can also make Memento extend some public interface and allow HistoryStack to access some of the fields. This provides good security against external objects since they cannot even reference the memento class, let alone accessing the saved state in the memento class.

The Calculator (Client) Class is responsible for handling of bussiness logic and also the logic for saving the state or doing undo as per the bussiness logic.

This pattern allows us to safely create and restore snapshots of objects without breaking the encapsulation. I hope you liked this article. I regularly write such articles on #LLD and #GoodCodingPractices. Follow Prateek Mishra and learn something new every week.

References

To write this article I took help from the following sources:

  1. https://refactoring.guru/design-patterns/memento
  2. https://en.proft.me/2017/02/27/memento-pattern-java-and-python/
  3. https://www.geeksforgeeks.org/stack-class-in-java/

要查看或添加评论,请登录

Prateek Mishra的更多文章

  • Performance Testing: An Overview

    Performance Testing: An Overview

    Performance testing is a crucial aspect of software development that ensures the quality and reliability of your…

    2 条评论
  • Builder Design Pattern

    Builder Design Pattern

    The builder pattern is a popular design pattern that is used to separate the construction of an object from its…

    5 条评论
  • Iterator Design Pattern

    Iterator Design Pattern

    Iterator design pattern is one of the most used design patterns. In this article we will discuss the what, why and how…

  • Command Design Pattern

    Command Design Pattern

    Command Pattern is one of the Behavioral Design Patterns which focuses on how objects and classes should communicate…

  • Chain of Responsibility Pattern

    Chain of Responsibility Pattern

    Consider that you need an allowance for your team and for that you need to take budget approval from your manager…

    1 条评论
  • Flyweight Design Pattern

    Flyweight Design Pattern

    Flyweight Pattern is a Structural Design Pattern which can be used to save memory by sharing fields between objects…

    1 条评论
  • Decorator Design Pattern

    Decorator Design Pattern

    Decorator / Wrapper is one of the most heavily used structural design pattern. You might have also come across it many…

    2 条评论
  • Composite Design Pattern

    Composite Design Pattern

    Corporate : Michael, we are having an audit. We need your branch's revenue data by the end of the day.

  • Bridge Design Pattern

    Bridge Design Pattern

    Bridge pattern is one of the Structural Design Patterns. Consider the problem given in the image below where there is…

  • Adapter Design Pattern

    Adapter Design Pattern

    An adapter is, like we all know, a bridge that facilitates communication between two incompatible interfaces. Adapter…

社区洞察