Re-learning design patterns (three, design patterns - memo pattern)

1. Memo mode

    In daily life, we sometimes use the Ctrl+Z key combination to undo the current operation when editing a document. When we browse the web, we click to return to the previous page. In the program, we often use the rollback operation in database transaction management, etc., all hoping to restore the data to the previous state.

    Over the years, this feature has become so common that everyone expects every application to support the fallback operation. The memo pattern we are going to learn today is used to do this.

1.1, what is the memo mode

  • definition

    Memento mode is a behavioral design mode, also known as snapshot mode, which refers to capturing the internal state of an object without breaking the encapsulation, and saving this state outside the object, so that the object can be restored to the original saved state when needed later.

    In layman's terms, the memo mode is an object's backup mode, which provides a backup method for program data. The specific method used to store the object state depends on the length of time the object needs to be saved.

The structure of the memento pattern:

    1) Originator role: records the internal state at the current moment, is responsible for defining which states belong to the backup range, is responsible for creating and restoring the memo data, and can access all the information in the memo;

    2) Memento role: responsible for storing the internal state of the initiator, and providing these internal states to the initiator when needed;

    3) Manager (Caretaker) role: manage, save and provide memos, but cannot access and modify the content of memos.

    The intent of the memento pattern is to provide storage and recovery functions for object states, and the saved state data of objects is inaccessible outside the object.

1.2. Advantages and disadvantages of memo mode

  • advantage

    1) A snapshot of the object can be generated without violating encapsulation;

    2) Simplify the initiator's code. The initiator does not need to manage and save the backup of its internal state. All information is stored in the memo and managed by the manager.

  • shortcoming

    Creating memos too frequently will cause the application to consume more memory.

1.3. Creation method

    Take the hero attribute in League of Legends as an example. After eating the red buff, the hero's combat effectiveness will be improved, and it will return to the previous state after it expires.

1) Originator role

//发起人角色,即原始对象,需要备份的对象
public class LolOriginator {

	private String name; //英雄名字
	private String type; //英雄类型
	private Integer  fightingNum; //英雄战斗力
	
	public LolOriginator(String name,String type,Integer fightingNum){
		this.name = name;
		this.type = type;
		this.fightingNum = fightingNum;
	}
	
	//创建一个备忘录,进行备忘操作
	public LolMemento createMemento(){
		return new LolMemento(this);
	}
	
	//恢复成指定备忘录
	public void restoreMemento(LolMemento memento){
		this.name = memento.getName();
		this.type = memento.getType();
		this.fightingNum = memento.getFightingNum();
	}
	
	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	public String getType() {
		return type;
	}
	
	public void setType(String type) {
		this.type = type;
	}

	public Integer getFightingNum() {
		return fightingNum;
	}

	public void setFightingNum(Integer fightingNum) {
		this.fightingNum = fightingNum;
	}
	
	@Override
	public String toString() {
		return this.getName()+"-"+this.getType()+"-"+this.getFightingNum();
	}
}

2) Memento role

//备忘录
public class LolMemento {

	private String name; //英雄名字
	private String type; //英雄类型
	private Integer  fightingNum; //英雄战斗力
	
	public LolMemento(LolOriginator lol){
		this.name=lol.getName();
		this.type=lol.getType();
		this.fightingNum = lol.getFightingNum();
	}

	public String getName() {
		return name;
	}

	public String getType() {
		return type;
	}

	public Integer getFightingNum() {
		return fightingNum;
	}
	
}

3) Caretaker role

//管理者,负责管理备忘录对象
public class LolCaretaker {

	private LolMemento memento;

	//如果有一连串的状态加成,可以保存多个状态
	//private List<LolMemento> mementoList = new ArrayList<LolMemento>();
	
	public LolMemento getMemento() {
		return memento;
	}

	public void setMemento(LolMemento memento) {
		this.memento = memento;
	}
	
}

4) client

public class Client {

	public static void main(String[] args) {
		//备忘录管理者
		LolCaretaker taker = new LolCaretaker();
		
		//创建一个英雄
		System.out.println("当前的英雄信息:");
		LolOriginator lol = new LolOriginator("德玛西亚之力", "战士", 666);
		System.out.println("  "+lol.toString());
		
		//进行一次备忘
		taker.setMemento(lol.createMemento());
		
		System.out.println("吃了一个红buff:");
		lol.setFightingNum(700);
		System.out.println("  "+lol.toString());
		
		System.out.println("红buff已经失效:");
		lol.restoreMemento(taker.getMemento());  //恢复到之前的状态
		
		System.out.println("  "+lol.toString());
		
	}
}

Case effect:

 

The UML diagram at this time:

1.4. Summary and Suggestions

    With the memento mode, the state of the object can be captured, and the saved state data of the object is inaccessible outside the object, which protects the integrity of the saved state data, which is also the advantage of the memo mode.

    What we may use more is to store the state of the object in another object or to support the persistent storage of objects across multiple sessions, and use object serialization to store object information, which is the prototype mode we learned earlier. The prototype mode can be a substitute for the memo mode. So the memo pattern is not commonly used.

Application scenario:

    1) The memento pattern can be used when you want to generate a snapshot of the state of the object so that you can restore the previous state of the object;

    2) When directly accessing the object's field getter and setter violates its encapsulation, the memo mode can be used.

Application of memo mode in JDK:

    All java.io.Serializable implementations can mock Memento

    javax.faces.component.StateHolder implementation

Guess you like

Origin blog.csdn.net/xiaoxianer321/article/details/125476637