备忘录模式的定义是:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。

该模式允许生成对象状态的快照和将其还原,主要用于撤销与重做功能的实现。

该模式存在 3 类角色:

  1. Originator 原始对象:创建和恢复备忘录
  2. Memento 备忘录对象
  3. Caretaker 负责人:保存备忘录
classDiagram
class Originator{
	- state
	+ backup()
	+ restore(m:Memento)
}
class Memento{
	- state
	+ Memento(state)
	+ getState()
}
class Caretaker{
	- history:Memento[]
	+ undo()
	+ redo()
}
Originator ..> Memento
Caretaker <|..> Memento

代码实现:

//数据对象  
@AllArgsConstructor  
@Data  
@ToString  
@NoArgsConstructor  
public class Text {  
    private String title;  
    private String content;  
}
//Originator原始对象  
public class Editor {  
    private Text text;  
    private History history;  
  
    public Editor() {  
        this.history = new History();  
    }  
    public Text getText() {  
        return text;  
    }  
  
    // 撤销  
    public void undo() {  
        history.undo();  
    }  
  
    // 重做  
    public void redo() {  
        history.redo();  
    }  
  
    // 恢复  
    public void restore(String data) {  
        text = JSON.parseObject(data, Text.class);  
    }  
  
    //备份  
    public String backup() {  
        return JSON.toJSONString(text);  
    }  
  
    public void doAction(String title, String content) {  
        text = new Text(title, content);  
        history.add(new Memento(this));  
    }  
}
//Caretaker负责人  
public class History {  
    List<Memento> mementos = new ArrayList<>();  
    private int curIndex;  
  
    public void add(Memento memento) {  
        if (curIndex + 1 != mementos.size()) {  
            mementos = mementos.subList(0, curIndex);  
        }  
        mementos.add(memento);  
        curIndex = mementos.size() - 1;  
    }  
  
    // 撤销  
    public void undo() {  
        curIndex = Math.max(0, curIndex - 1);  
        Memento memento = mementos.get(curIndex);  
        memento.restore();  
    }  
  
    // 重做  
    public void redo() {  
        curIndex = Math.min(mementos.size(), curIndex + 1);  
        Memento memento = mementos.get(curIndex);  
        memento.restore();  
    }  
}
// 备忘录对象  
@Data  
public class Memento {  
    //值对象,存储数据  
    private String state;  
    private Editor editor;  
  
    public Memento(Editor editor) {  
        this.editor = editor;  
        // 备份  
        state=this.editor.backup();  
    }  
  
    public void restore(){  
        editor.restore(state);  
    }  
}
Editor editor=new Editor();  
editor.doAction("1","1");  
editor.doAction("2","2");  
editor.undo();  
System.out.println(editor.getText());  
editor.redo();  
System.out.println(editor.getText());
// 结果是:
//Text(title=1, content=1)
//Text(title=2, content=2)

备忘录模式的优点是能在不破坏封装性的前提下创建对象的快照。