文章目录
- 前言
- 一、概念
- 二、核心结构
- [三、Java 代码实现(编辑器撤销)](#三、Java 代码实现(编辑器撤销))
-
- [1. 备忘录(快照)](#1. 备忘录(快照))
- [2. 原发器(编辑器)](#2. 原发器(编辑器))
- [3. 看管人(历史记录)](#3. 看管人(历史记录))
- [4. 客户端测试](#4. 客户端测试)
- 四、严格封装(最佳实践)
- 五、优缺点
- 六、应用场景
- [七、备忘录 VS 命令 VS 状态](#七、备忘录 VS 命令 VS 状态)
- 八、总结
前言
开发中经常需要撤销、回滚、快照、恢复 功能:比如编辑器 Ctrl+Z、游戏存档、订单回滚、配置恢复。如果直接把对象内部状态暴露出去,会破坏封装;如果自己管理备份,代码又会臃肿。备忘录模式 就是专门解决状态备份与恢复、且不破坏封装的行为型设计模式。
一、概念
备忘录模式(Memento Pattern) 是一种行为型设计模式 ,核心思想:
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后可以将该对象恢复到原先保存的状态。
简单理解:
- 原发器(Originator):要备份的对象(如编辑器)
- 备忘录(Memento):存储状态的快照(不可篡改)
- 看管人(Caretaker):只负责保存快照,不看内容
一句话总结:
存档 → 快照 → 读档,且快照内容谁都不能改。
二、核心结构
- Originator(原发器)
创建备忘录、从备忘录恢复状态。 - Memento(备忘录)
存储内部状态,只允许原发器读取。 - Caretaker(看管人)
持有备忘录,不能访问/修改内容,只负责存和取。
三、Java 代码实现(编辑器撤销)
场景:编辑器内容备份与恢复(Ctrl+Z)
1. 备忘录(快照)
java
// 备忘录:存储状态,不可修改
public class EditorMemento {
private final String content;
public EditorMemento(String content) {
this.content = content;
}
// 只给原发器用
public String getContent() {
return content;
}
}
2. 原发器(编辑器)
java
// 原发器:创建快照、恢复快照
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 restoreFromMemento(EditorMemento memento) {
this.content = memento.getContent();
}
}
3. 看管人(历史记录)
java
// 看管人:只保存备忘录,不看内容
public class History {
private EditorMemento memento;
public void setMemento(EditorMemento memento) {
this.memento = memento;
}
public EditorMemento getMemento() {
return memento;
}
}
4. 客户端测试
java
public class Client {
public static void main(String[] args) {
Editor editor = new Editor();
History history = new History();
// 编辑内容
editor.setContent("第1版内容");
// 存档
history.setMemento(editor.createMemento());
// 修改
editor.setContent("第2版修改内容");
System.out.println("当前:" + editor.getContent());
// 撤销(恢复)
editor.restoreFromMemento(history.getMemento());
System.out.println("撤销后:" + editor.getContent());
}
}
输出:
当前:第2版修改内容
撤销后:第1版内容
四、严格封装(最佳实践)
为了防止外部篡改备忘录,通常做法:
- Memento 设为私有内部类
- 只暴露窄接口(空接口)给 Caretaker
- 只有 Originator 能访问宽接口
这样绝对安全,不会破坏封装。
五、优缺点
优点
- 不破坏封装实现备份/恢复
- 职责分离:原发器管业务,看管人管存储
- 可实现撤销、回滚、快照、重做
- 易于实现多版本管理
缺点
- 频繁备份会消耗大量内存
- 状态复杂时,备忘录管理成本高
- 某些语言难以保证备忘录不可篡改
六、应用场景
- 编辑器撤销(Ctrl+Z)
- 游戏存档/读档
- 事务回滚、订单取消
- 配置恢复、系统快照
- 虚拟机 checkpoint、容器快照
经典应用:
- IDEA/Eclipse 撤销重做
- Git commit(可理解为备忘录)
- Spring StateMachine 状态保存
- database transaction rollback
七、备忘录 VS 命令 VS 状态
- 备忘录:保存/恢复状态
- 命令:封装行为,支持撤销
- 状态:状态决定行为
八、总结
- 备忘录模式 = 快照 + 存档 + 恢复
- 核心:不破坏封装,安全备份状态
- 结构:
Originator+Memento+Caretaker - 是实现撤销、回滚、存档最标准的设计模式