一、备忘录模式
备忘录模式(Memento Pattern)保存一个对象的某个状态,以便在适当的时候恢复对象。备忘录模式属于行为型模式。

-
原发器(Originator)角色:原发器根据需要决定将自己的哪些内部状态保存到备忘录中,并可以使用备忘录来恢复内部状态。
-
备忘录(Memento)角色:负责存储原发器对象的内部状态,但是具体需要存储哪些状态是由原发器对象来决定的。另外备忘录应该只能由原发器对象来访问它内部的数据,原发器外部的对象不应该访问到备忘录对象的内部数据。为了控制对备忘录对象的访问,备忘录模式中出现了窄接口和宽接口的概念。
- 窄接口:管理者只能看到备忘录的窄接口,窄接口的实现中通常没有任何的方法,只是一个类型标识。窄接口使得管理者只能将备忘录传递给其他对象。
- 宽接口:原发器能够看到备忘录的宽接口,从而可以从备忘录中获取到所需的数据,来将自己恢复到备忘录中所保存的状态。理想情况是:只允许生成备忘录的原发器来访问该备忘录的内部状态,通常实现成为原发器内的一个私有内部类。
-
管理者(Caretaker)角色:备忘录管理者,或者称为备忘录负责人。主要负责保存好备忘录对象,但是不能对备忘录对象的内容进行操作或检查。
二、备忘录模式实现方式
1、备忘录角色
//宽接口
public class Memento {private String state;public Memento(String state){this.state = state;}public String getState(){return state;}
}//窄接口
public interface Memento {}
2、原发器角色
//宽接口
public class Originator {private String state;public void setState(String state){this.state = state;}public String getState(){return state;}public Memento saveStateToMemento(){return new Memento(state);}public void getStateFromMemento(Memento Memento){state = Memento.getState();}
}//窄接口
public class Originator {private String state;public void setState(String state){this.state = state;}public String getState(){return state;}public Memento saveStateToMemento(){return new MementoImpl(state);}public void getStateFromMemento(Memento Memento){MementoImpl mementoImpl = (MementoImpl) memento;state = Memento.getState();}/*** 真正的备忘录对象,实现了备忘录窄接口 实现成私有的内部类,不让外部访问*/private static class MementoImpl implements Memento {private String state;public MementoImpl(String state) {super();this.state = state;}public String getState() {return state;}}
3、管理者角色
对备忘录进行管理、保存和提供备忘录,只能将备忘录传递给其他角色
public class CareTaker {private List<Memento> mementoList = new ArrayList<>();public void add(Memento state){mementoList.add(state);}public Memento get(int index){return mementoList.get(index);}
}
4、测试
public class MementoPatternDemo {public static void main(String[] args) {Originator originator = new Originator();CareTaker careTaker = new CareTaker();originator.setState("State #1");originator.setState("State #2");careTaker.add(originator.saveStateToMemento());originator.setState("State #3");careTaker.add(originator.saveStateToMemento());originator.setState("State #4");System.out.println("Current State: " + originator.getState()); originator.getStateFromMemento(careTaker.get(0));System.out.println("First saved State: " + originator.getState());originator.getStateFromMemento(careTaker.get(1));System.out.println("Second saved State: " + originator.getState());}
}
结果
Current State: State #4
First saved State: State #2
Second saved State: State #3
三、备忘录模式总结
优点
- 状态恢复机制,使得用户可以方便地回到一个特定的历史步骤,当新的状态无效或者存在问题时,可以使用暂时存储起来的备忘录将状态复原。
- 信息的封装,一个备忘录对象是一种原发器对象状态的表示,不会被其他代码所改动。备忘录保存了原发器的状态,采用列表、堆栈等集合来存储备忘录对象可以实现多次撤销操作。
缺点
- 如果需要保存的状态过多时,每一次保存都会消耗很多内存(所以可以结合原型模式使用)。
使用场景
- 需要保存和恢复数据的相关场景;
- 提供一个可回滚的操作,如ctrl+z、浏览器回退按钮、Backspace键等;
- 需要监控的副本场景;

















