备忘录模式,也叫快照模式,它可以在不破坏封装性的前提下捕获一个对象的内部状态,并在对象之外保存这个状态,以便在需要的时候恢复到原先保存的状态。
常见的场景比如游戏进度日志,VMWare操作系统快照等,以备后续的恢复。
备忘录模式有三个角色,一是源发器,二是对源发器状态进行记录的备忘录,三是备忘录的管理者。
示例代码
/**
* @author Created by njy on 2023/7/1
* 1.备忘录(Memento):备忘录,保存编辑器的状态
* 定义:存储源发器对象的状态。备忘录对象可以包括一个或多个状态属性,源发器可以根据需要保存和恢复状态。
*/
public class EditorMemento {
//文本内容 (可以是属性、也可以是对象)
private String content;
public EditorMemento(String content) {
this.content = content;
}
public String getContent() {
return content;
}
}
/**
* @author Created by njy on 2023/7/1
* 2.源发器(Originator):文本编辑器
* 定义:需要保存和恢复状态的对象。它创建一个备忘录对象,用于存储当前对象的状态,也可以使用备忘录对象恢复自身的状态。
*/
public class Editor {
//内容(可以是属性、也可以是对象)
private String content;
public void setContent(String content) {
this.content = content;
}
public String getContent() {
return content;
}
// 创建备忘录对象,保存当前状态
public EditorMemento createMemento() {
return new EditorMemento(content);
}
// 恢复备忘录对象保存的状态
public void restoreMemento(EditorMemento memento) {
content = memento.getContent();
}
}
/**
* @author Created by njy on 2023/7/2
* 3.管理者(Caretaker):历史记录
* 定义:负责保存备忘录对象,但不能修改备忘录对象的内容。它可以存储多个备忘录对象,并决定何时将备忘录恢复给源发器。
*/
public class History {
//备忘录可以保存多个状态
private final List<EditorMemento> mementos = new ArrayList<>();
// 保存备忘录对象的状态
public void push(EditorMemento memento) {
mementos.add(memento);
}
// 弹出(移除)最近保存的备忘录对象,并返回它
public EditorMemento pop() {
int lastIndex = mementos.size() - 1;
EditorMemento lastMemento = mementos.get(lastIndex);
mementos.remove(lastIndex);
return lastMemento;
}
}
/**
* @author Created by njy on 2023/7/2
* 备忘录模式测试类
*/
@SpringBootTest
public class TestMemento {
@Test
void testMemento(){
//创建文本编辑器(源发器)
Editor editor = new Editor();
//创建管理者
History history = new History();
// 编辑文本并保存状态
editor.setContent("Hello");
history.push(editor.createMemento());
// 编辑更多文本并再次保存状态
editor.setContent("Hello, Java!");
history.push(editor.createMemento());
editor.setContent("Hello,world!");
System.out.println("当前内容: " + editor.getContent());
// 恢复之前的状态
editor.restoreMemento(history.pop());
System.out.println("恢复后上一次内容: " + editor.getContent());
editor.restoreMemento(history.pop());
System.out.println("恢复后上二次内容: " + editor.getContent());
}
}