Memento Design Pattern | You need to keep state

Asiri Gunasena

Published:

Design Pattern

Memento Design Pattern

Memento Design Pattern introduces to captures the internal state of a given object and keeps storing it to restore into a given state of an object. This is saving the checkpoint of an object and restoring it to its previous state once needed.

Memento Design Pattern comes under behavioral patterns (Design Patterns). In computing, the Memento Design Pattern is heavily used in different methodologies, by using different words like undo, redo, rollback, tag, stash, etc but uses a similar concept of keeping track of the state of a project or a file when changing on it. If there is a problem with recent then there is a possibility to undo or check the difference between recent and older ones.

There are three main components in the pattern going to describe.

  • Originator: This is saving the state of the object. Memento objects are saved by the Originator for future use.
  • Caretaker: Keep track of the Object state and retrieve it once it is needed. Once the Originator wants to save the state of the object Caretaker saves it itself.
  • Memento: Keep the state of an object. This is a snapshot of the object once takes the object state.

Let’s move on to the Real-world use of the Memento Design Pattern.

Memento Design Pattern Real-World Example

Consider that once we are doing programming, we need to use a repository management system like GIT, SVN, CVS, etc. Just for simplicity let’s take the Application file and continue the example with how it keeps the states of a file. The below example demonstrates the class diagram of application file-making states.

Memento Design Pattern
Memento Pattern for simple repository management system

Memento Design Pattern in Java

import java.util.ArrayList;
import java.util.List;

//Memento : Keep the state of object
class FileMemento{

   private String id;
   private String name;
   private String content;

   public FileMemento(String id, String name, String content) {
      this.id = id;
      this.name = name;
      this.content = content;
   }
   public String getId() {
      return id;
   }
   public String getName() {
      return name;
   }
   public String getContent() {
      return content;
   }
   public void setContent(String content) {
      this.content = content;
   }
}

//Originator :Memento objects save by Originator 
class FileOriginator  
{
    private String id;
    private String name;
    private String content;
     
    public FileOriginator(String id, String name) {
        super();
        this.id = id;
        this.name = name;
    }

   public String getContent() {
      return content;
   }     
   public void setContent(String content) {
      this.content = content;
   }         
   public FileMemento tagMemento() 
   {
     FileMemento m = new FileMemento(id, name, content);
     return m;
   }
   public void restore(FileMemento m) {
      this.id = m.getId();
      this.name = m.getName();
      this.content = m.getContent();
   }
   @Override
   public String toString() {
       return "File [id=" + id + ", Name=" + name + ", content=" + content + "]";
   }
}
// CareTaker: Keep track of Object state 
class RepositoryCareTaker{
   
   private List<FileMemento> mementoList = new ArrayList<FileMemento>();
   public void add(FileMemento state){
      mementoList.add(state);
   }
   public FileMemento get(int index){
      return mementoList.get(index);
   }
}

//Client: Use the the feature of the Pattern;
public class MementoUserClient {
   public static void main(String[] args) {
      FileOriginator originator = new FileOriginator("Memento001","Memento001.java");
      RepositoryCareTaker careTaker = new RepositoryCareTaker();
      
      originator.setContent("First content of the file");
      careTaker.add(originator.tagMemento());
      originator.setContent("Second content of the file");
      careTaker.add(originator.tagMemento());      
      originator.setContent("Third content of the file");
      careTaker.add(originator.tagMemento());
      System.out.println("Current State: " + originator);		
      originator.restore(careTaker.get(1));
      System.out.println("Current State: " + originator);	
      originator.restore(careTaker.get(0));
      System.out.println("Current State: " + originator);	
   }
}

Output

Current State: File [id=Memento001, Name=Memento001.java, content=Third content of the file]
Current State: File [id=Memento001, Name=Memento001.java, content=Second content of the file]
Current State: File [id=Memento001, Name=Memento001.java, content=First content of the file]

Advantages of Memento Design Pattern

  • Compare changes with old versions and identify changes
  • Revert to the upper version
  • Redo to the previous state once deleted by mistake.
  • Create versions with different states

Design Patterns Book

Design Patterns are one of the most famous solutions in programing and millions of people follow them to fix their tasks, design projects, and so on. Most of the patterns create based on basic OOP concepts (If your beginner then read our basic OOP, Encapsulation, Inheritance, Polymorphism, and Abstraction articles with great examples )

There are a lot of articles and design pattern books available with different examples to read. Other than our article if you are interested in this topic you could go through the below books as well.

BooksDescription

Head First Design Patterns: A Brain-Friendly Guide
My favorite and it’s more readable. There are good examples and they look good to beginners as well.

Design Patterns: Elements of Reusable Object-Oriented Software
There are 23 design patterns. showing how to select an appropriate pattern for your case.

Head First Design Patterns: Building Extensible and Maintainable Object-Oriented Software
There are a lot of simple examples showing how to use design patterns in the correct way. Those are based on SOLIC principles.
Design Patterns ebook online

There are a lot of design pattern ebooks on Amazon. Those design patterns are written with great examples in a different programming language. I included a few of them according to their best ranking.

ennicode

Address: 89/1 Rabbegamuwa, Handessa, Kandy, Central, Sri Lanka

Email to: Primary: [email protected]

Services

E-Learning

Company Websites

Support and Configuration work

Banners, Covers, and Post

Web Development & Configurations

Content Writing and Marketing

Contact

Ennicode