备忘录模式(Memento Pattern)是一种行为型设计模式,主要用于在不破坏对象封装性的前提下捕获并外部化对象的内部状态,从而可以在以后将对象恢复到原先保存的状态。这种模式常用于实现撤销操作、历史记录回溯等功能。
备忘录模式的核心组成部分:
-
Originator(发起人)
负责创建一个备忘录,用于记录当前时刻自身的内部状态,并可以使用备忘录恢复内部状态。
-
Memento(备忘录)
用于存储 Originator 的内部状态。备忘录需要保护其内容不被除 Originator 之外的对象访问,以保证封装性。
-
Caretaker(管理者)
负责保存备忘录,但不能对备忘录的内容进行操作或检查。它主要负责备忘录的存取管理。
备忘录模式的应用场景
- 文本编辑器中的撤销功能:用户每执行一次操作(如输入、删除等),系统都会保存当前状态到备忘录中。当用户点击撤销时,可以通过备忘录恢复到上一个状态。
- 游戏存档功能:玩家在游戏过程中可以保存当前进度(角色位置、生命值、装备等),并在需要时加载之前的存档。
- 事务回滚机制:在数据库操作中,如果某些事务失败,可以通过备忘录模式回滚到事务开始前的状态。
示例代码(Java)
以下是一个简单的备忘录模式实现示例:
java
// 发起人类
class Originator {
private String state;
public void setState(String state) {
this.state = state;
}
public String getState() {
return state;
}
// 创建备忘录
public Memento saveStateToMemento() {
return new Memento(state);
}
// 从备忘录恢复状态
public void getStateFromMemento(Memento memento) {
state = memento.getState();
}
}
// 备忘录类
class Memento {
private String state;
public Memento(String state) {
this.state = state;
}
public String getState() {
return state;
}
}
// 管理者类
class Caretaker {
private List<Memento> mementoList = new ArrayList<>();
public void add(Memento state) {
mementoList.add(state);
}
public Memento get(int index) {
return mementoList.get(index);
}
}
// 测试备忘录模式
public class MementoPatternDemo {
public static void main(String[] args) {
Originator originator = new Originator();
Caretaker caretaker = new Caretaker();
// 设置状态并保存到备忘录
originator.setState("State #1");
caretaker.add(originator.saveStateToMemento());
originator.setState("State #2");
caretaker.add(originator.saveStateToMemento());
originator.setState("State #3");
System.out.println("Current State: " + originator.getState());
// 恢复到之前的状态
originator.getStateFromMemento(caretaker.get(0));
System.out.println("Restored State: " + originator.getState());
}
}
输出结果
Current State: State #3
Restored State: State #1
优点
- 封装性:备忘录模式对外隐藏了对象的内部状态,确保只有发起人可以访问和修改这些状态。
- 简化撤销操作:通过保存多个备忘录,可以轻松实现多级撤销功能。
- 职责分离:发起人专注于状态管理,而管理者专注于备忘录的存取。
缺点
- 内存开销:如果需要保存的状态数据较大或频繁保存,可能会占用较多内存。
- 复杂性增加:引入备忘录和管理者后,代码结构会变得更加复杂。