Memorandum mode, also known as Snapshot Pattern or Token pattern, is the behavior pattern of objects.
A memo object is an object that stores snapshots of the internal state of another object. The purpose of the memo mode is to capture and externalize the state of an object without destroying the encapsulation, so that it can be restored to the stored state at the appropriate time in the future. Memorandum mode is often used in conjunction with command mode and iteration sub-mode.
Structure of Memorandum Model
The structure of the memorandum pattern is shown below.
The memorandum model involves three roles: the Memento role, the Originator role and the Caretaker role.
Memento role
The memorandum roles also have the following responsibilities:
1. Store the internal state of the Originator object. A memorandum can determine how many internal states of the Originator object are stored based on the judgment of the initiator object.
2. A memo can protect its content from being read by any object other than the Originator object.
The MOU has two equivalent interfaces:
Narrow interface: The Caretaker object (and any other object except the initiator object) sees the narrow interface of the memo, which only allows it to pass the memo object to other objects.
Wide interface: Contrary to the narrow interface seen by the responsible object, the initiator object can see a wide interface, which allows it to read all the data in order to restore the internal state of the initiator object.
Originator role
The Originator role has the following responsibilities:
Create a memo object with the current internal state.
Memory objects are used to store their internal state.
Caretaker role
The Caretaker role has the following responsibilities:
Responsible for saving memo objects.
Do not check the contents of the memo object.
Implementation of "White Box" Memorandum Model
A memo role provides an interface to any object, that is, a wide interface, and the state stored within the memo role is exposed to all objects. So this implementation is also called "white box implementation".
The "white box" implementation stores the status of the sponsor's role in a place that everyone can see, thus destroying the encapsulation. But programmer self-discipline can also achieve most of the intentions of the pattern to a certain extent. So white box implementation is still meaningful.
Originator role
/**
* Created by yangtianrui on 17-3-18.
* Initiator role
*/
public class Originator {
// Simulate a state
private String mState;
public Originator(String state) {
mState = state;
}
public void setState(String state) {
mState = state;
}
public Memento createMemento() {
return new Memento(mState);
}
// Output status
public void printState() {
System.out.println(mState);
}
}
Memento role
/**
* Created by yangtianrui on 17-3-18.
* A memo object that stores the state of Originator
*/
public class Memento {
private String mState;
public String getState() {
return mState;
}
public void setState(String state) {
mState = state;
}
public Memento(String state) {
mState = state;
}
}
CareTaker role
/**
* Created by yangtianrui on 17-3-18.
* The person in charge role, the person in charge saves the state of the object
*/
public class CareTaker {
private Memento mMemento;
public CareTaker(Memento memento) {
mMemento = memento;
}
/**
* Get status
*/
public String retrieveState() {
return mMemento.getState();
}
/**
* In-state
*/
public void saveState(Memento memento) {
mMemento = memento;
}
}
Test class
public class Main {
public static void main(String[] args) {
// Initialization state
final Originator originator = new Originator("Initial state.");
originator.printState();
// Use CareTaker to save state
final CareTaker careTaker = new CareTaker(originator.createMemento());
// modify state
originator.setState("Modify this state.");
// Modified state of output
originator.printState();
// Use Memento to restore state
originator.setState(careTaker.retrieveState());
// Output recovery status
originator.printState();
/*Result
Initial state.
Modify this state.
Initial state.
*/
}
}
Implementation of "Black Box" Memorandum Model
In the Java language, the way to implement dual interfaces is to design the memo role class as an internal member class of the initiator role class.
Setting Memento as an internal class of Originator class encapsulates the Memento object in Originator.
An identification interface, MementoIF, is provided externally to Caretaker and other objects.
Thus, the Originator class sees all the interfaces of Menmento, while Caretaker and other objects see only the interfaces exposed by the identification interface MementoIF.
Design of Wide and Narrow Interface
IMemento
Provide only a simple interface to the outside world
/**
* Created by yangtianrui on 17-3-18.
* Memorandum Interface Provided Externally
*/
public interface IMemento {
}
Originator role, encapsulating memos through internal classes
public class Originator {
// Simulate saved state
private String mState;
public Originator(String state) {
mState = state;
}
public void setState(String state) {
mState = state;
}
public void printState() {
System.out.println(mState);
}
// Create a Memorandum Save Object
public IMemento createMemento() {
// Save objects
return new OriginMemento(mState);
}
// Recovery from the Memorandum
public void restoreMemento(IMemento memento) {
if (memento instanceof OriginMemento) {
mState = ((OriginMemento) memento).getState();
}
}
/**
* Encapsulation of object state through internal classes
*/
private class OriginMemento implements IMemento {
private String mState;
public OriginMemento(String state) {
mState = state;
}
public String getState() {
return mState;
}
public void setState(String state) {
mState = state;
}
}
}
CareTaker role, managing memos
public class CareTaker {
// External performance is only an interface, reflecting the encapsulation.
private IMemento mMemento;
public void setMemento(IMemento memento) {
mMemento = memento;
}
public IMemento getMemento() {
return mMemento;
}
}
Test class
public class Main {
public static void main(String[] args) {
// Initial state
final Originator originator = new Originator("Initial state.");
originator.printState();
// Storage status to memo
final CareTaker careTaker = new CareTaker();
careTaker.setMemento(originator.createMemento());
// Change status
originator.setState("Modified state.");
originator.printState();
// Recovery status
originator.restoreMemento(careTaker.getMemento());
originator.printState();
/*
Result
*Initial state.
*Modified state.
*Initial state.
*/
}
}
Code download: https://github.com/yangtianrui95/Design-Patterns