定义:作用是保存对象的内部状态,并在需要的时候恢复以前的状态,在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样就可在需要时将该对象恢复到以前的状态。
结构图:
涉及的角色
发起人角色::负责创建一个备忘录对象,用于存储当前时刻originator自己的内部状态,originator可以根据需要决定将自己的哪些状态信息存储在备忘录中,并可使用备忘录恢复内部状态。
备忘录角色:负责存储originator对象的内部状态,并可防止originator以外的其他对象访问备忘录,备忘录有两个接口,负责人角色只能看到备忘录的饿窄接口,只能将备忘录的对象传递给其他对象,originator却能看到备忘录的宽接口,这个接口允许读取所有的数据,以便根据这些数据返回这个发起人的内部状态
负责人角色:在适当的时间保存/恢复originator对象的状态,不检查备忘录对象的内容
应用场景:
1、备忘录模式比较适用功能比较复杂,需要维护或记录属性历史的类,或者需要保存的属性是众多属性的一小部分,originator可根据保存的备忘录信息还原到前一状态。
2、如果在程序中使用到命令模式的撤销功能,那么可用备忘录模式存储可撤销操作的状态
3、当角色的状态改变时,有可能这个状态无效,此时可暂时存储的备忘录将状态复原。
优缺点
优点:①有时一些发起人对象的内部信息必须保存在发起人对象以外的地方,但是必须要由发起人对象自己读取,这时,使用备忘录模式可以把复杂的发起人内部信息对其他的对象屏蔽起来,从而可以恰当地保持封装的边界。②本模式简化了发起人类,发起人不再需要管理和保存其内部状态的一个个版本,客户端可以自行管理他们所需要的这些状态的版本;③当发起人角色的状态改变的时候,有可能这个状态无效,这时候就可以使用暂时存储起来的备忘录将状态复原。
缺点:①如果发起人角色的状态需要完整地存储到备忘录对象中,那么在资源消耗上面备忘录对象会很昂贵。②当负责人角色将一个备忘录 存储起来的时候,负责人可能并不知道这个状态会占用多大的存储空间,从而无法提醒用户一个操作是否很昂贵;③当发起人角色的状态改变的时候,有可能这个协议无效。如果状态改变的成功率不高的话,不如采取“假如”协议模式。
public class Original {
private String state;
public Original(String state){
this.state = state;
}
public void setState(String state){
this.state = state;
}
public String getState(){
return state;
}
public Memento createMemento(){
return new Memento(state);
}
public void restoreMemento(Memento memento){
this.state = memento.getState();
}
}
public class Memento {
private String state;
public Memento(String state){
this.state = state;
}
public void setState(String state){
this.state = state;
}
public String getState(){
return state;
}
}
public class Storage {
private Memento memento;
public Storage(Memento memento){
this.memento = memento;
}
public void setMemento(Memento memento){
this.memento = memento;
}
public Memento getMemento(){
return memento;
}
}
public class Test {
public static void main(String[] args) {
Original original = new Original("ori");
Storage storage = new Storage(original.createMemento());
original.setState("change");
original.restoreMemento(storage.getMemento());
System.out.println("恢复后 "+original.getState());
}
}