备忘录模式解决"保存和恢复对象状态"的问题——不破坏封装的前提下,把对象状态存成快照,需要时回滚。编辑器的撤销、游戏的存档就是它的场景。这篇讲清它怎么保存/恢复状态。
一、解决什么问题:保存和恢复状态
编辑器要支持"撤销"——把文档从当前状态回退到上一步。但对象的内部状态(字段)通常被封装保护,外部不能随便读。
备忘录模式:对象自己生成一个"状态快照"(备忘录),外部只负责保存快照,需要时用快照恢复。
二、核心结构
java
// 备忘录:保存对象的状态快照(不可变,只有原对象能读懂)
class EditorMemento {
private final String content; // 快照内容
EditorMemento(String content) { this.content = content; }
String getContent() { return content; }
}
// 发起人:编辑器,能创建快照、恢复快照
class Editor {
private String content = "";
void type(String text) { content += text; }
EditorMemento save() { return new EditorMemento(content); } // 创建快照
void restore(EditorMemento m) { this.content = m.getContent(); } // 恢复
String getContent() { return content; }
}
// 管理者:只保存快照,不动内容
class History {
private Deque<EditorMemento> stack = new ArrayDeque<>(); // 撤销栈
void push(EditorMemento m) { stack.push(m); }
EditorMemento pop() { return stack.pop(); }
}
// 使用:编辑 → 存快照 → 撤销 = 恢复上一个快照
Editor editor = new Editor();
editor.type("hello");
History history = new History();
history.push(editor.save()); // 存快照 1
editor.type(" world");
history.push(editor.save()); // 存快照 2
editor.restore(history.pop()); // 撤销 → 回到快照 1("hello")关键:EditorMemento 是快照,Editor 自己能创建和恢复它,History 只负责存(不碰内容)。这样既保存了状态,又不破坏 Editor 的封装。
三、核心价值
- 不破坏封装:状态快照由对象自己生成,外部存/取不碰内部字段
- 支持撤销/回滚:用栈存快照,pop 就能回退
四、实际应用
- 编辑器撤销:Ctrl+Z = 弹出上一个快照恢复
- 游戏存档:存档 = 保存状态快照,读档 = 恢复
- 事务回滚:出错时恢复到之前的状态
小结
- 备忘录 = 对象状态快照,支持保存/恢复
- 快照由对象自己生成,不破坏封装
- 典型:编辑器撤销、游戏存档、事务回滚
相关:《命令模式》(命令的 undo 常配合备忘录存快照,两者常一起用实现撤销)。
