Design Pattern

Memento Pattern Design Patterns in java

The memento pattern comes under the behavioral patterns in object-oriented programming. In the memento pattern, the object is given the facility to restore its preceding state. The three objects include, the originator, a caretaker plus a memento object, are required to implement memento pattern.

The internal state is stored in the originator object. The caretaker object performs an operation on the originator; however it requires to be able to undo changes that occur to the originator. The caretaker object requests the originator object for the memento object first, and then it performs the operations or the sequence of the operations on the originator. To go back to the previous state, the caretaker returns this memento object back to the Originator object. Hence, the object of memento is unable to be altered by the caretaker object. It is an opaque object. The memento pattern can only be applied to a singular object, so if the caretaker object changes other objects, a special attention is required.

The Memento Pattern

According to the Gang of Four:

Without violating encapsulation, capture and externalize an object’s internal state so that the object can be restored to this state later.

To design, versatile and reusable object-oriented software, there is 23 well-known Gang of Four (GoF) design patterns, the memento pattern is one of them. There are some problems that memento pattern caters. The internal state of the object is supposed to be stored externally so that when it comes to restoration of the object, this externally stored, internal state can be used. The encapsulation of the object should not be violated. The object needs to be encapsulated because the data structure (representation) of the object is stored inside it, which cannot be and should not be accessed from outside of the object.

The pattern defines an object, the originator object that saves the internal state of the objects in a memento object and restores the object to its previous state using a memento object. The memento can only be accessed by the originator object that created it in the first place. The caretaker object requests the originator for a memento object, in which it stores the object’s internal state and then return that memento object back to the originator, in order to restore the object’s previous state. This way, the originator can be saved and restored without having to violate its encapsulation.

Spring 5 Design Pattern Book

You could purchase my Spring 5 book that is with title name “Spring 5 Design Pattern“. This book is available on the Amazon and Packt publisher website. Learn various design patterns and best practices in Spring 5 and use them to solve common design problems. You could use author discount to purchase this book by using code- “AUTHDIS40“.

The memento object is capable of storing the internal state of the Originator object. The state may include a number of state variables. The memento object must store two interfaces. The interface to the caretaker and the interface to the originator object. This interface to the caretaker is not supposed to allow any operations to be performed or any access to the internal state, which is stored by the memento, which honors the encapsulation.

The interface to the originator is supposed to allow the originator object to be able to access any state variables which are required by the originator to restore the previous state. The originator object is capable of creating a memento object, which stores the internal state of the originator. It also uses the memento object to restore its previous state. The caretaker object is supposed to keep the memento object but is not allowed to access or operate on the memento object.

UML class Diagram of this Pattern

Let’s see the following class diagram of the Memento Design Pattern and its component classes.

Memento:

It stores internal state of the Originator object.

Originator:

It creates a memento containing a snapshot of its current internal state.

Caretaker:

It is responsible for the memento’s safekeeping.

Sample Example for Memento Design Pattern

Let’s see the following real world example for this pattern. This real-world code demonstrates the Memento pattern which temporarily saves and then restores the SalesProspect’s internal state.

Step 1: Create Memento class.
Memento.java

/**
 * 
 */
package com.doj.patterns.behavior.momento;

/**
 * @author Dinesh.Rajput
 *
 */
public class Memento {
	
	 private String _name;

	 private String _phone;

	 private double _budget;

	public Memento(String _name, String _phone, double _budget) {
		super();
		this._name = _name;
		this._phone = _phone;
		this._budget = _budget;
	}

	public String get_name() {
		return _name;
	}

	public void set_name(String _name) {
		this._name = _name;
	}

	public String get_phone() {
		return _phone;
	}

	public void set_phone(String _phone) {
		this._phone = _phone;
	}

	public double get_budget() {
		return _budget;
	}

	public void set_budget(double _budget) {
		this._budget = _budget;
	}
	 
}

Step 2: Create Originator class
SalesProspect.java

/**
 * 
 */
package com.doj.patterns.behavior.momento;

/**
 * @author Dinesh.Rajput
 *
 */
public class SalesProspect {
	
    private String _name;

    private String _phone;

    private double _budget;

	public String get_name() {
		return _name;
	}

	public void set_name(String _name) {
		this._name = _name;
		System.out.println("Name:  " + _name);
	}

	public String get_phone() {
		return _phone;
	}

	public void set_phone(String _phone) {
		this._phone = _phone;
		System.out.println("Phone: " + _phone);
	}

	public double get_budget() {
		return _budget;
	}

	public void set_budget(double _budget) {
		this._budget = _budget;
		System.out.println("Budget: " + _budget);
	}
    
	// Stores memento
    public Memento saveMemento(){
    	System.out.println();
    	System.out.println("Saving state --");
    	System.out.println();
    	return new Memento(_name, _phone, _budget);
    }

    // Restores memento
    public void restoreMemento(Memento memento){
    	System.out.println();
    	System.out.println("Restoring state --");
    	System.out.println();
    	this.set_name(memento.get_name());
    	this.set_phone(memento.get_phone());
    	this.set_budget(memento.get_budget());
    }
}

Step 3: Create CareTaker class
ProspectMemory.java

/**
 * 
 */
package com.doj.patterns.behavior.momento;

/**
 * @author Dinesh.Rajput
 *
 */
public class ProspectMemory {
	
	private Memento _memento;

	public Memento get_memento() {
		return _memento;
	}

	public void set_memento(Memento _memento) {
		this._memento = _memento;
	}
	
}

Step 4: Use CareTaker and Originator objects.
MementoPatternDemo.java

/**
 * 
 */
package com.doj.patterns.behavior.momento;

/**
 * @author Dinesh.Rajput
 *
 */
public class MementoPatternDemo {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		SalesProspect salesProspect = new SalesProspect();
		salesProspect.set_name("Dinesh Rajput");
		salesProspect.set_phone("4482-133-111");
		salesProspect.set_budget(25000.0);

		// Store internal state
		ProspectMemory prospectMemory = new ProspectMemory();
		prospectMemory.set_memento(salesProspect.saveMemento());

		// Continue changing originator
		salesProspect.set_name("Arnav Rajput");
		salesProspect.set_phone("6682-122-111");
		salesProspect.set_budget(1000000.0);

		// Restore saved state
		salesProspect.restoreMemento(prospectMemory.get_memento());
	}

}

Step 5: Let’s run this demo class and verify the output.

Name:  Dinesh Rajput
Phone: 4482-133-111
Budget: 25000.0

Saving state --

Name:  Arnav Rajput
Phone: 6682-122-111
Budget: 1000000.0

Restoring state --

Name:  Dinesh Rajput
Phone: 4482-133-111
Budget: 25000.0

Previous
Next
Dinesh Rajput

Dinesh Rajput is the chief editor of a website Dineshonjava, a technical blog dedicated to the Spring and Java technologies. It has a series of articles related to Java technologies. Dinesh has been a Spring enthusiast since 2008 and is a Pivotal Certified Spring Professional, an author of a book Spring 5 Design Pattern, and a blogger. He has more than 10 years of experience with different aspects of Spring and Java design and development. His core expertise lies in the latest version of Spring Framework, Spring Boot, Spring Security, creating REST APIs, Microservice Architecture, Reactive Pattern, Spring AOP, Design Patterns, Struts, Hibernate, Web Services, Spring Batch, Cassandra, MongoDB, and Web Application Design and Architecture. He is currently working as a technology manager at a leading product and web development company. He worked as a developer and tech lead at the Bennett, Coleman & Co. Ltd and was the first developer in his previous company, Paytm. Dinesh is passionate about the latest Java technologies and loves to write technical blogs related to it. He is a very active member of the Java and Spring community on different forums. When it comes to the Spring Framework and Java, Dinesh tops the list!

Share
Published by
Dinesh Rajput

Recent Posts

Strategy Design Patterns using Lambda

Strategy Design Patterns We can easily create a strategy design pattern using lambda. To implement…

2 years ago

Decorator Pattern using Lambda

Decorator Pattern A decorator pattern allows a user to add new functionality to an existing…

2 years ago

Delegating pattern using lambda

Delegating pattern In software engineering, the delegation pattern is an object-oriented design pattern that allows…

2 years ago

Spring Vs Django- Know The Difference Between The Two

Technology has emerged a lot in the last decade, and now we have artificial intelligence;…

2 years ago

TOP 20 MongoDB INTERVIEW QUESTIONS 2022

Managing a database is becoming increasingly complex now due to the vast amount of data…

2 years ago

Scheduler @Scheduled Annotation Spring Boot

Overview In this article, we will explore Spring Scheduler how we could use it by…

3 years ago