Memo mode


Memento Pattern saves a certain state of an object so that the object can be restored at the appropriate time. The memo mode is a behavioral mode.

Introduction

Intent: Capture the internal state of an object and save this state outside the object without destroying encapsulation.

Main solution: The so-called memo mode is to capture the internal state of an object without destroying the encapsulation, and save this state outside the object, so that the object can be used later Restore to the originally saved state.

When to use: Many times we always need to record the internal state of an object. The purpose of this is to allow the user to cancel uncertain or wrong operations and restore to his original state. His condition gave him a "regret medicine" to take.

How to solve: Specially store the object state through a memo class.

Key code: The client is not coupled with the memo class, but coupled with the memo management class.

Application examples: 1. Regret medicine. 2. Save files while playing games. 3. ctri + z in Windows. 4. Back in IE. 4. Database transaction management.

Advantages: 1. It provides users with a mechanism to restore the state, which allows users to return to a certain historical state more conveniently. 2. Encapsulation of information is realized so that users do not need to care about the details of saving the state.

Disadvantages: Consumption of resources. If a class has too many member variables, it will inevitably occupy relatively large resources, and each save will consume a certain amount of memory.

Usage scenarios: 1. Relevant status scenarios where data needs to be saved/restored. 2. Provide a rollback operation.

Notes: 1. In order to comply with the Dimit principle, a class for managing memos must be added. 2. In order to save memory, you can use prototype mode + memo mode.

Implementation

Memento mode uses three classes Memento, Originator and CareTaker. Memento contains the state of the object to be restored. Originator creates and stores state in Memento objects. The Caretaker object is responsible for restoring the object's state from Memento.

MementoPatternDemo, our demo class uses the CareTaker and Originator objects to display the state restoration of the object.

memento_pattern_uml_diagram.jpg

Step 1

Create the Memento class.

Memento.java

public class Memento {
   private String state;

   public Memento(String state){
      this.state = state;
   }

   public String getState(){
      return state;
   }	
}

Step 2

Create the Originator class.

Originator.java

public class Originator {
   private String state;

   public void setState(String state){
      this.state = state;
   }

   public String getState(){
      return state;
   }

   public Memento saveStateToMemento(){
      return new Memento(state);
   }

   public void getStateFromMemento(Memento Memento){
      state = Memento.getState();
   }
}

Step 3

Create the CareTaker class.

CareTaker.java

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

public class CareTaker {
   private List<Memento> mementoList = new ArrayList<Memento>();

   public void add(Memento state){
      mementoList.add(state);
   }

   public Memento get(int index){
      return mementoList.get(index);
   }
}

Step 4

Use the CareTaker and Originator objects.

MementoPatternDemo.java

public class MementoPatternDemo {
   public static void main(String[] args) {
      Originator originator = new Originator();
      CareTaker careTaker = new CareTaker();
      originator.setState("State #1");
      originator.setState("State #2");
      careTaker.add(originator.saveStateToMemento());
      originator.setState("State #3");
      careTaker.add(originator.saveStateToMemento());
      originator.setState("State #4");

      System.out.println("Current State: " + originator.getState());		
      originator.getStateFromMemento(careTaker.get(0));
      System.out.println("First saved State: " + originator.getState());
      originator.getStateFromMemento(careTaker.get(1));
      System.out.println("Second saved State: " + originator.getState());
   }
}

Step 5

Verify the output.

Current State: State #4
First saved State: State #2
Second saved State: State #3