设计模式-备忘录模式
备忘录模式(Memento Pattern)是一种行为型设计模式,允许在不破坏封装的前提下,捕获一个对象的内部状态,并在未来需要时将其恢复。备忘录模式在需要保存和恢复对象状态的场景下非常实用,比如撤销操作、历史记录功能等。
备忘录模式的角色组成:
- 发起人(Originator):
- 负责创建备忘录对象并保存自己的状态,同时可以使用备忘录恢复其状态。
- 备忘录(Memento):
- 用于存储发起人的内部状态,通常是一个简单的数据类。
- 管理者(Caretaker):
- 负责存储和管理备忘录,不能直接操作备忘录的内容,只能通过发起人恢复状态。
示例代码:文本编辑器的撤销功能
问题背景
假设有一个简单的文本编辑器,支持输入文本和撤销操作。为了实现撤销功能,需要保存每次输入的状态,并在用户撤销时恢复之前的状态。
实现代码
// 备忘录类:存储状态
class Memento {
private final String state; // 文本内容
public Memento(String state) {
this.state = state;
}
public String getState() {
return state;
}
}
// 发起人类:文本编辑器
class TextEditor {
private String content = ""; // 当前文本内容
// 创建备忘录
public Memento save() {
return new Memento(content);
}
// 恢复备忘录
public void restore(Memento memento) {
this.content = memento.getState();
}
// 添加文本
public void append(String text) {
content += text;
}
// 获取当前内容
public String getContent() {
return content;
}
}
// 管理者类:负责管理备忘录
class Caretaker {
private final List<Memento> history = new ArrayList<>(); // 保存备忘录的历史记录
private int currentIndex = -1; // 当前备忘录的索引
// 添加备忘录
public void save(Memento memento) {
// 如果在中途操作,清除后续历史
while (currentIndex < history.size() - 1) {
history.remove(history.size() - 1);
}
history.add(memento);
currentIndex++;
}
// 撤销操作
public Memento undo() {
if (currentIndex <= 0) {
System.out.println("无法撤销!");
return null;
}
currentIndex--;
return history.get(currentIndex);
}
// 恢复操作
public Memento redo() {
if (currentIndex >= history.size() - 1) {
System.out.println("无法恢复!");
return null;
}
currentIndex++;
return history.get(currentIndex);
}
}
// 客户端
public class MementoPatternExample {
public static void main(String[] args) {
TextEditor editor = new TextEditor();
Caretaker caretaker = new Caretaker();
// 第一次编辑
editor.append("Hello");
caretaker.save(editor.save()); // 保存状态
System.out.println("当前内容: " + editor.getContent());
// 第二次编辑
editor.append(", World!");
caretaker.save(editor.save()); // 保存状态
System.out.println("当前内容: " + editor.getContent());
// 撤销
editor.restore(caretaker.undo());
System.out.println("撤销后内容: " + editor.getContent());
// 再次撤销
editor.restore(caretaker.undo());
System.out.println("再次撤销后内容: " + editor.getContent());
// 恢复
editor.restore(caretaker.redo());
System.out.println("恢复后内容: " + editor.getContent());
}
}
输出结果:
当前内容: Hello
当前内容: Hello, World!
撤销后内容: Hello
再次撤销后内容:
恢复后内容: Hello
备忘录模式的优点:
- 封装性良好:
- 备忘录对外隐藏了发起人的内部状态,只能通过发起人进行状态的保存和恢复。
- 简化撤销和恢复功能:
- 非常适合需要撤销和恢复功能的场景,管理复杂状态变更变得简单。
- 遵循单一职责原则:
- 备忘录只负责存储状态,发起人负责逻辑处理,管理者负责保存和恢复。
备忘录模式的缺点:
- 内存消耗较大:
- 如果状态信息较多,保存多个备忘录可能会占用大量内存。
- 实现复杂度较高:
- 在某些场景下,管理备忘录的逻辑可能变得复杂。
备忘录模式的适用场景:
- 需要保存对象状态以支持撤销/恢复功能。
- 对象的内部状态需要完全封装,避免被其他代码直接访问。
- 需要在某些操作失败后,恢复到之前的状态。
备忘录模式广泛应用于编辑器、游戏存档、事务回滚等场景。

浙公网安备 33010602011771号