简介
为什么要使用备忘录模式
在许多软件中都需要撤销功能,若需要实现撤销,必须要记录历史状态。当用户需要取消操作并且返回到某个历史状态时,可以取出事先保存的历史状态来覆盖当前状态。备忘录模式可以解决如何实现保存历史状态的问题。
什么是备忘录模式
备忘录模式(Memento Pattern):在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。
别名
Token
类型
对象行为型模式
角色
角色
- Originator:原发器
- 具体类
- 定义备份哪些内部状态。
- 创建备忘录。
- 存储状态。
- 恢复状态。
- Memento:备忘录
- 具体类
- 负责存储原发器状态。原发器根据需要决定备忘录存储原发器的哪些状态。
- 防止原发器以外的其他对象访问备忘录。原发器实际上提供了两个接口,管理者Caretaker只能将备忘录传递给其他对象。而原发器能够访问返回到先前状态的所有数据。
- Caretaker:管理者
- 保存和提供备忘录。
- 不能对备忘录进行操作或检查。
UML类图
实现
- 创建原发器Originator.java
- 创建备忘录Memento.java
- 创建管理者Caretaker.java
- 创建测试类Client.java
原发器
Originator.java
class Originator {
private String state;
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
// 创建备忘录对象
public Memento createMemento() {
return new Memento(this.state);
}
// 根据备忘录对象恢复原发器
public void restoreMemento(Memento memento) {
this.setState(memento.getState());
}
}
备忘录
Memento.java
class Memento {
private String state = "";
public Memento(String state) {
this.state = state;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
管理者
Caretaker.java
class Caretaker {
private Memento memento;
public Memento getMemento() {
return memento;
}
public void setMemento(Memento memento) {
this.memento = memento;
}
}
测试类
Client.java
public class Client {
public static void main(String[] args){
Originator originator = new Originator();
originator.setState("状态1");
System.out.println("初始状态:"+originator.getState());
Caretaker caretaker = new Caretaker();
caretaker.setMemento(originator.createMemento());
originator.setState("状态2");
System.out.println("修改后状态:"+originator.getState());
originator.restoreMemento(caretaker.getMemento());
System.out.println("撤銷后状态:"+originator.getState());
}
}
测试Client.java
运行Client.java的main()
初始状态:状态1
修改后状态:状态2
撤銷后状态:状态1
优缺点
优点
- 提高系统安全性。
缺点
- 资源消耗大。实际应用中,普遍要保存多状态多级备忘录。如果原发器在生成备忘录时必须拷贝并存储大量信息,或客户非常频繁的创建或恢复原发器状态,会导致大量的开销。
适用环境
- 需要回滚功能。必须保存一个状态在某一时刻的状态,这样以后需要时它才能恢复到先前的状态。
- 创建或恢复触发器开销不大。
使用场景
- 文本编辑器的Ctrl+Z
- 数据库中事务操作
扩展
- Command可使用备忘录来为可撤销的操作维护状态。
- 备忘录可用于迭代Iterator。
问题
多次撤销如何实现?
待补充。
在软件开发中,你在哪里用到了备忘录模式?
待补充。