备忘录设计模式
备忘录模式(Memento Pattern)是一种行为设计模式,用于捕获对象的内部状态并在需要时恢复该状态,同时不破坏对象的封装性。它适用于需要实现撤销/重做、历史记录或状态快照的场景。
核心组件
Originator(原发器)
- 需要保存状态的对象
- 提供创建备忘录和恢复状态的方法
- 示例代码:
public class TextEditor {private String content;public void write(String text) {this.content = text;}// 创建备忘录public TextMemento save() {return new TextMemento(content);}// 从备忘录恢复public void restore(TextMemento memento) {this.content = memento.getSavedContent();} }
Memento(备忘录)
- 存储 Originator 的内部状态
- 通常设计为不可变对象
- 示例代码:
public final class TextMemento {private final String content;public TextMemento(String content) {this.content = content;}// 仅允许原发器访问String getSavedContent() {return content;} }
Caretaker(管理者)
- 负责保存和管理备忘录
- 不能修改备忘录内容
- 示例代码:
import java.util.Stack;public class History {private final Stack<TextMemento> states = new Stack<>();public void saveState(TextMemento state) {states.push(state);}public TextMemento getLastState() {return states.pop();} }
工作流程
graph LRA[Originator] -- 创建 --> B[Memento]B -- 存储 --> C[Caretaker]C -- 提供 --> AA -- 恢复状态 --> B
关键特性
封装保护
- Memento 通过私有访问控制保护状态
- Caretaker 只能存储备忘录,不能修改内容
状态管理
- 支持多级撤销:使用栈结构存储历史状态
- 状态隔离:每个备忘录独立存储对象快照
内存优化
- 增量存储:仅保存变化部分
- 懒加载:需要时再生成备忘录
适用场景
- 需要实现撤销/重做功能(如文本编辑器)
- 需要保存对象历史状态(如游戏存档)
- 需要隔离状态生成和存储逻辑
优缺点分析
优点
- 保持对象封装边界
- 简化原发器职责(SRP原则)
- 支持多状态管理
缺点
- 可能增加内存消耗
- Caretaker 需维护生命周期
- 频繁保存可能影响性能
扩展实现
// 客户端使用示例
public class Client {public static void main(String[] args) {TextEditor editor = new TextEditor();History history = new History();editor.write("First draft");history.saveState(editor.save()); // 保存状态1editor.write("Revised content");history.saveState(editor.save()); // 保存状态2editor.restore(history.getLastState()); // 撤销到状态1}
}
设计建议
- 对大型对象使用增量备忘录
- 通过接口约束备忘录访问权限
- 结合原型模式优化状态克隆性能
- 使用对象池管理频繁创建的备忘录