备忘录模式:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象回复到原先保存的状态。
备忘录角色分类:
Memento(备忘录)角色:负责存储Originator对象的内部状态,并可防止Originator以外的其他对象访问备忘录。备忘录实际上有两个接口,“备忘录管理者角色”只能看到备忘录提供的窄接口——对于备忘录角色中存放的属性是不可见的。“备忘发起角色”则能够看到一个宽接口——能够得到自己放入备忘录角色中属性。
备忘发起(Originator)角色:“备忘发起角色”创建一个备忘录,用以记录当前时刻它的内部状态。在需要时使用备忘录恢复内部状态。
备忘录管理者(Caretaker)角色:负责保存好备忘录。不能对备忘录的内容进行操作或检查。
我们了解一下简单的两种不同的备忘录实现:
”白箱”备忘录模式的实现
public class Memento {
private int state;
public Memento(int state) {
this.state = state;
System.out.println("备忘录 当前保存 状态:" + state);
}
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
}
public class Originator {
private int state = 0;
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
/**
* 将发起人恢复到备忘录对象所记载的状态
*/
public void restoreMemento(Memento memento) {
this.state = memento.getState();
System.out.println("恢复 备忘录 状态:" + state);
}
//返回当前备忘录
public Memento creatMementoObject() {
return new Memento(state);
}
}
public class Caretaker {
private Memento memento;
public Memento getMemento() {
return memento;
}
public void setMemento(Memento memento) {
this.memento = memento;
}
}
public static void main(String[] args) {
Originator originator = new Originator();
originator.setState(5);
System.out.println("现在状态为:"+originator.getState());
Caretaker caretaker = new Caretaker();
caretaker.setMemento(originator.creatMementoObject());
originator.setState(8);
System.out.println("现在状态为:"+originator.getState());
originator.restoreMemento(caretaker.getMemento());
System.out.println("现在状态为:"+originator.getState());
}
然后就是相对的黑箱备忘录,我们看一下黑箱的图。
其实也就吧Memento 的类抽象成接口。对Memento有更高的可扩展性,所以就不进行代码展示了。只需要对外暴露接口就可以了。
多重检查点
前面所给出的白箱和黑箱的示意性实现都是只存储一个状态的简单实现,也可以叫做只有一个检查点。常见的系统往往需要存储不止一个状态,而是需要存储多个状态,或者叫做有多个检查点。
备忘录模式可以将发起人对象的状态存储到备忘录对象里面,备忘录模式可以将发起人对象恢复到备忘录对象所存储的某一个检查点上。
个人认为黑盒更加符合开闭原理,是一个更好的备忘录实现方法。