Memento Design Pattern in Java

This tutorial explains Gang of Four’s Memento design pattern in Java. It starts with explaining the Memento pattern’s definition, followed by the two mandatory requirements which must be met for applying the pattern. Next, it shows the UML class diagram for Memento pattern and explains the roles of the various constituent classes of the pattern. An example use case showing Memento pattern implementation is then explained using its class diagram, Java code for implementation and detailed explained of the code.

Introduction: Memento Design Pattern is a behavioral design pattern among the Gang Of Four(GOF)Article on GOF Patterns & their types Design Patterns. Being a behavioral design pattern, the memento pattern basically deals with how the objects communicate and share responsibilities among each other.

What is Memento Design Pattern
Memento design pattern provides ability to capture(save) an object’s state and then restore back this captured state when required by the system.

Memento design pattern can be chosen when the following 2 requirements occur in conjunction –

  1. The state of an object in the system needs to be captured/saved so that the object can be restored to that state later.
  2. Direct access to object’s state is not an option as that would break the encapsulation of object by exposing its internal structure.

Its important to understand the above two points to understand the applicable scenarios where Memento Pattern can be chosen for designing the system being implemented. If the system, of which the state is being saved, does not want the state saving or restoring process to know about internal implementation details of how the state is being handled by the system then Memento is to be used. I.e. the Memento pattern moves the part of saving and restoring of the state of the system to a separate set of classes which do not care about what makes up the state or how the system uses that state. Instead classes of Memento only care about storing the state when needed and reproducing it back on demand.

This separation of concerns between the actual system state and the memento implementation allows for single responsibility principleClick to Read tutorial on Single Responsibility Principle being effectively applied. This is because the responsibility of handling the system’s state is separated from the state capture and restoring responsibility.

Class Diagram for Memento Design Pattern

Memento Design Pattern Class Diagram

Explanation of Memento Design Pattern’s Class Diagram:

  • There are 3 main participants in the memento pattern’s class diagrams – Originator, Memento and Caretaker.
  • Originator is the object of which the state is to be stored. The responsibilities of storing the snapshot of its state and then restoring the state from Memento lie with Originator. This is the reason why the methods createMementoFromState()(for storing the state) and setStateFromMemento()(for restoring the state) have been defined on the Originator.
  • Memento stores the internal state of the Originator. Only Originator is allowed storing to/restoring from the Memento object. This allows the internal structure/state of Originator to not be visible to other classes thus achieving the encapsulation requirement of a Memento implementation.
  • Caretaker holds the memento object and is responsible for its safekeeping. When a snapshot of the Originator’s state is required then the Caretaker asks the Originator for the snapshot as a memento object and stores the snapshot. When the Originator’s state is to be restored then Caretaker passes the Memento object back to the Originator.
  • There is also a State class which holds the state of the Originator. Memento also holds this state of the Originator. As this is simply the representation of Originator’s internal state hence there is no separate class for State depicted in the class diagram. However, in the java example’s class diagram, which is next, I have included the State class also.

Memento Design Pattern – Example Use Case in Java – Class Diagram:

Memento Design Pattern in Java Class Diagram
Code for the classes shown in Java Example’s Class Diagram
//PlayerStatus.java
public class PlayerStatus{
 private long playerPoints;
 private int playerLevel;
 public void setPlayerPoints(long playerPoints){
  this.playerPoints=playerPoints; 
 }
 public long getPlayerPoints(){
  return this.playerPoints; 
 }
 public void setPlayerLevel(int playerLevel){
  this.playerLevel=playerLevel; 
 }
 public int getPlayerLevel(){
  return this.playerLevel; 
 }
}
//PlayerStatusMemento.java
public class PlayerStatusMemento{
 private PlayerStatus playerStatus;
 public void setPlayerStatus(PlayerStatus playerStatus){
   this.playerStatus=playerStatus;
 }
 public PlayerStatus getPlayerStatus(){
  return this.playerStatus ;
 }
}
//CurrentPlayerStatus.java
public class CurrentPlayerStatus{
  private int playerLevel=1;
  private long playerPoints=0;
  public void setStatusFromMemento(PlayerStatusMemento memento){
    this.playerLevel=memento.getPlayerStatus(). getPlayerLevel();
    this.playerPoints=memento.getPlayerStatus(). getPlayerPoints();
  } 
  public PlayerStatusMemento createMementoFromStatus(){
    PlayerStatusMemento memento=new PlayerStatusMemento();
    PlayerStatus playerStatus=new PlayerStatus();
    playerStatus.setPlayerLevel(this.playerLevel);
    playerStatus.setPlayerPoints(this.playerPoints);
    memento.setPlayerStatus(playerStatus);
    return memento;
  }
  public void setPlayerPoints(long playerPoints){
   this.playerPoints=playerPoints; 
  }
  public long getPlayerPoints(){
  return this.playerPoints; 
  }
  public void setPlayerLevel(int playerLevel){
   this.playerLevel=playerLevel; 
  }
  public int getPlayerLevel(){
   return this.playerLevel; 
  }
}
//PlayerStatusCaretaker.java  
public class PlayerStatusCaretaker{
 public static void main(String args[]){
   PlayerStatusMemento playerStatusMemento; 
   System.out.println("Game Started");
   CurrentPlayerStatus currentPlayerStatus=new CurrentPlayerStatus();
   currentPlayerStatus.setPlayerPoints(1200L);
   currentPlayerStatus.setPlayerLevel(2);
   System.out.println("Player reached 2nd level with 1200 points"); 
   printCurrentPlayerStatus(currentPlayerStatus);
   System.out.println("Player stores current status as memento"); 
   playerStatusMemento= currentPlayerStatus.createMementoFromStatus();
   currentPlayerStatus.setPlayerPoints(2200L);
   currentPlayerStatus.setPlayerLevel(4);
   printCurrentPlayerStatus(currentPlayerStatus);
   System.out.println("At this point player loses & is relegated to status saved in memento"); 
   currentPlayerStatus.setStatusFromMemento(playerStatusMemento);
   printCurrentPlayerStatus(currentPlayerStatus);
 }
 public  static void printCurrentPlayerStatus(CurrentPlayerStatus currentPlayerStatus){
   System.out.println("Player points->"+currentPlayerStatus.getPlayerPoints()+",level->"+currentPlayerStatus.getPlayerLevel());
 }
}
 OUTPUT on running the PlayerStatusCaretaker.java
Game Started
Player reached 2nd level with 1200 points
Player points->1200,level->2
Player stores current status as memento
Player points->2200,level->4
At this point player loses & is relegated to status saved in memento
Player points->1200,level->2
Explanation of Java Example’s Class Diagram & Code
The Java class diagram above depicts Memento pattern implemented for a game which needs to keep track of player points & player level as the game is being played

  • PlayerStatus represents the state of the Originator(CurrentPlayerStatus). The State/PlayerStatus consists of two attributes – playerPoints and playerLevel.
  • PlayerStatusMemento is the memento object which stores an instance of PlayerStatus which is nothing but a snapshot of CurrentPlayingStatus’s internal state.
  • CurrentPlayerStatus is the Originator i.e the object of which we need to store/restore the internal snapshot. CurrentPlayerStatus holds its state in two attributes playerPoints and playerLevel which are the exact same attributes in PlayerStatus object which is stored in the PlayerStatusMemento object.
  • PlayerStatusCaretaker in the above example drives the game and stores/restores the memento with the help of Originator. It starts the game. As the game progresses and the player reaches level 2 with 1200 points, PlayerStatusCaretaker asks the CurrentPlayerStatus(Originator) object to create a memento object and store the current PlayerStatus by calling its method createMementoFromStatus(). The player then moves to 2200 points and level 4 where he,hypothetically, loses a life and goes down to the last state stored. This is the state stored in the PlayerStatusMemento object which the PlayerStatusCaretaker sets by invoking the setStatusFromMemento(Momento) method of CurrentPlayerStatus. The gameplayer’s status is thus restored to 1200 points and level 2.
  • So, to sum-up, we were able to store a snapshot of CurrentPlayerStatus and then restore it later. This is how the Memento Design Pattern works.

Summary
In the above tutorial we looked at what is memento design pattern,its class diagram with explanation. We then looked at a Java Use Case implementing Memento pattern through its class diagram, code for the classes shown in the java based class diagram, followed by explanation of both the class diagram & code. This concludes the tutorial on Memento design pattern.

 

Digiprove sealCopyright © 2014-2017 JavaBrahman.com, all rights reserved.