备忘录模式简介
备忘录(Memento):在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
类图:
核心类说明:
Originator:需要被备份的对象
State:对象属性对象
Memento:备忘录对象
Caretaker:备忘录管理对象,维护所有备忘录
使用示例
public class Originator {
private State state;
public Originator(){
this.state = new State();
state.setVersion(0);
}
public Memento createMemento(){
State newState = null;
try {
newState = (State)state.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return new Memento(newState);
}
public void showState(){
System.out.println(" version:" + state.getVersion());
}
public void addVersion(){
this.state.setVersion(this.state.getVersion() + 1);
}
public void readMemento(Memento memento){
this.state = memento.getState();
}
}
public class State implements Cloneable{
private int version;
public int getVersion() {
return version;
}
public void setVersion(int version) {
this.version = version;
}
@Override
public Object clone() throws CloneNotSupportedException {
// clone() 方法对属性进行逐个复制,但引用类型属性只会浅拷贝,需要深拷贝则重写
return super.clone();
}
}
public class Memento {
private State state;
public Memento(State state) {
this.state = state;
}
public State getState() {
return state;
}
}
public class Caretaker {
Map<String,Memento> mementos = new HashMap<>();
public void addMemento(String key, Memento memento){
mementos.put(key,memento);
}
public Memento getMemento(String key){
return mementos.get(key);
}
}
public class Client {
public static void main(String[] args) {
Originator originator = new Originator();
Caretaker caretaker = new Caretaker();
originator.showState();
caretaker.addMemento("version0",originator.createMemento());
originator.addVersion();
originator.showState();
originator.readMemento(caretaker.getMemento("version0"));
originator.showState();
}
}
结果输出:
version:0
version:1
version:0
总结
优缺点
备忘录模式将需要保存的细节全部封装至备忘录对象中,使客户端不需要知道属性细节也可以进行保存和回滚,需要修改保存内容时修改备忘录对象即可。
备忘录模式通过对象保存内容,一旦滥用就意味着会产生大量的备忘录对象,在保存的内容又特别多的时候将十分占用内存,同时由于其内容保存在内存中,数据十分容易丢失。可以考虑将备忘录对象持久化到硬盘或数据库解决数据丢失问题。
笔者缺乏实际备忘录模式使用经验,以上问题仅供参考。
使用场景
Memento模式比较适用于功能比较复杂的,但需要维护或记录属性历史的类,或者需要保存的属性只是众多属性中的一小部分时,Originator可以根据保存的Memento信息还原到前一状态。