备忘录模式
备忘录模式用于在不破坏对象封装的前提下,保存对象某一时刻的状态,并在之后恢复。
一句话理解:给对象拍一张状态快照,需要时回滚。
解决什么问题
很多系统需要撤销或恢复:
- 编辑器撤销。
- 表单草稿。
- 游戏存档。
- 配置版本回滚。
- 工作流状态恢复。
如果外部直接读取对象所有内部字段再保存,会破坏封装。备忘录模式让对象自己创建快照,外部只负责保存快照。
基本结构
text
Originator -> createMemento()
Originator -> restore(memento)
Caretaker -> 保存 memento
Memento -> 状态快照角色:
Originator:原始对象,负责创建和恢复快照。Memento:备忘录,保存状态。Caretaker:负责人,只保存快照,不理解快照内容。
Java 示例
文本编辑器:
java
class Editor {
private String content = "";
public void write(String text) {
content += text;
}
public String content() {
return content;
}
public Snapshot save() {
return new Snapshot(content);
}
public void restore(Snapshot snapshot) {
this.content = snapshot.content();
}
}快照对象:
java
class Snapshot {
private final String content;
Snapshot(String content) {
this.content = content;
}
public String content() {
return content;
}
}历史记录管理:
java
import java.util.ArrayDeque;
import java.util.Deque;
class History {
private final Deque<Snapshot> snapshots = new ArrayDeque<>();
public void push(Snapshot snapshot) {
snapshots.push(snapshot);
}
public Snapshot pop() {
return snapshots.pop();
}
public boolean isEmpty() {
return snapshots.isEmpty();
}
}使用:
java
Editor editor = new Editor();
History history = new History();
editor.write("hello");
history.push(editor.save());
editor.write(" world");
editor.restore(history.pop());
System.out.println(editor.content()); // hello使用场景
- 撤销/重做。
- 草稿保存。
- 版本回滚。
- 状态恢复。
- 事务补偿前的状态保存。
优点
- 不破坏对象封装。
- 快照创建和恢复由对象自己负责。
- 容易实现撤销能力。
缺点
- 快照可能占用大量内存。
- 深拷贝状态可能比较复杂。
- 快照版本多时需要清理策略。
- 不适合保存超大对象完整状态。
实战注意
备忘录保存的是状态,不是操作。保存大对象时要考虑增量快照、压缩、过期清理,否则内存和存储会很快膨胀。