定义
备忘录模式(Memento):又称标记模式(Token),在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可以将该对象恢复到原先保存的状态(目的)。
类图及角色
备忘录角色(Memento):存储“备忘发起角色”的内部状态,备忘发起角色决定备忘录角色存储哪些内部状态。备忘录角色有宽接口(备忘发起角色能看到)和窄接口(备忘录管理角色能看见)。
备忘发起角色(Originator):创建一个备忘录用以记录当前时刻它的内部状态。
备忘录管理角色(Caretaker):负责保存备忘录。不能对备忘录的内容进行操作或检查。
//备忘发起角色
public class Originator {
//状态是私有的
private String state;
public Memento createMemento() {
return new Memento(this.state);
}
public void recoverMemento(Memento memento) {
this.setState(memento.getState());
}
public void show() {
System.out.println("state = " + this.state);
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
//备忘录角色
public 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;
}
}
//备忘管理角色
public class CareTaker {
private Memento memento;
public Memento getMemento() {
return memento;
}
public void setMemento(Memento memento) {
this.memento = memento;
}
}
//客户端
public class MementoClient {
public static void main(String[] args) {
// 设置初始状态
Originator originator = new Originator();
originator.setState("On");
originator.show();
// 管理者通过备忘录保存状态,由于有了很好地封装,可以隐藏Originator的实现细节
CareTaker careTaker = new CareTaker();
careTaker.setMemento(originator.createMemento());
// 改变状态
originator.setState("Off");
originator.show();
// 通过管理者从备忘录中恢复状态
originator.recoverMemento(careTaker.getMemento());
originator.show();
}
}
备忘录模式实现的3种方法
- 通过宽接口和窄接口实现。
- 通过内部类实现。(把备忘录角色作为备忘发起角色的一个私有内部类)
- 使用clone方法来简化备忘录角色(简化)。
实际应用中需要保存备忘发起角色大量的历史状态,最简单的方法是使用容器(list)按照顺序存放,这样就能很好地实现redo、undo功能了。
备忘录角色适用情况
- 需要保存对象在某一个时刻的(部分)状态。
- 不破坏对象的封装性。
备忘录模式和命令模式的不同
- 一个保存Object的状态,一个保存命令。
- 执行对象不同,保存状态的对象也不同,执行的操作也不同。
- 备忘录模式更加稳定,命令模式执行更加广泛。