在不破坏封装性的前提下,捕捉一个对象的内部状态,并在该对象之外保存这个状态,这样以后就可以将该对象恢复到原来保存的状态。为了允许用户取消不确定的操作,或从错误中恢复过来,需要实现检查点和取消机制,而要实现这些机制,你必须事先将状态信息保存在某处,这样才能将对象恢复到它们先前的状态。
备忘录对象可以存储另外一个对象在某个瞬间的内部状态,而这另外一个对象就被称为备忘录的原发器。原发器用描述当前状态的信息初始化该备忘录,只要原发器可以向备忘录中存储信息,备忘录对其他对象“不可见”。
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 {
Memento memento = null;
public Memento getMemento() {
return memento;
}
public void setMemento(Memento memento) {
this.memento = memento;
}
}
public class Originator {
private String state;
public void changeState(String state) {
System.out.println(String.format("Change to %s, the original state is %s", state, this.state));
this.state = state;
}
public void setMemento(Memento m) {
state = m.getState();
}
public Memento createMemento() {
return new Memento(state);
}
}
public class Cleint {
@Test
public void test() {
Originator org = new Originator();
Caretaker care = new Caretaker();
//修改原发器状态
org.changeState("StateA");
//负责人存储当前状态
care.setMemento(org.createMemento());
//修改原发器状态
org.changeState("StateB");
//使用负责人存储的状态恢复原发器状态
org.setMemento(care.getMemento());
//获取当前的状态
System.out.println(org.createMemento().getState());
}
}
Originator对象作为原发器,能够创建自己的备忘录,用来保存自己的内部状态,并且还能够使用备忘录对象Memento恢复到记录的那个状态。Caretaker对象只是单纯的保存Memento对象,并不会影响到它的状态。Memento对象表示一个状态,它可以存储复杂的状态,并可以将这些状态通过接口返回给Originator,从而使Originator能够恢复到Memento中记录的状态。Client中的代码首先修改了Originator中的状态,然后让Caretaker记录这个状态,之后再次修改Originator的状态,最后使用Caretaker中存储的状态恢复Originator。
当然这个模式还可以更复杂一点,可以将操作历史记录在备忘录中,然后就可以实现撤销操作,这样备忘录就和命令模式结合了起来。