备忘录模式:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。后期可以直接将该对象恢复到原先保存的状态。
备忘录模式
备忘录模式 Memento[məˈmentoʊ] Pattern
:常用于存档,编辑回退等场景,主要是保存某个对象当前的状态。
类图结构
结构解析
Originator[əˈrɪdʒəˌnetɚ]
发起者,复杂类有多个属性。负责创建一个备忘录,用于记录当前内部状态,并可以使用备忘录恢复状态。Originator
来决定需要备忘录存储哪些状态或属性。
Memento
备忘录,负责存储 Originator
指定的内部状态。只能通过 Originator
创建修改状态,其他类仅仅可以获取状态。
CareTaker
管理类,负责存储管理保存好的备忘录列表,但是不能修改备忘录中保存的状态。
Originator
负责指定 Memento
保存自己的哪些内部状态,CareTaker
维护一个列表保存 Memento
,后期可以通过这个列表恢复到指定状态。
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
| public class Memento { private String state;
public Memento(String state) { this.state = state; }
public String getState() { return state; } }
public class Originator { private String state; private String otherInfo;
public Memento createMemento(){ return new Memento(state); }
public void restore(Memento memento){ state = memento.getState(); }
public String getState() { return state; }
public void setState(String state) { this.state = state; }
public String getOtherInfo() { return otherInfo; }
public void setOtherInfo(String otherInfo) { this.otherInfo = otherInfo; } }
public class CareTaker { private List<Memento> mementos = new ArrayList<>();
public void addMemento(Memento memento){ mementos.add(memento); }
public Memento getMemento(int index){ return mementos.get(index); }
public void removeMemento(Memento memento){ mementos.remove(memento); }
public int size(){ return mementos.size(); } }
public class TestMemento { public static void main(String[] args) { Originator originator = new Originator(); originator.setState("first state"); originator.setOtherInfo("other info");
CareTaker careTaker = new CareTaker(); careTaker.addMemento(originator.createMemento());
originator.setState("second state"); originator.setState("third state"); careTaker.addMemento(originator.createMemento()); System.out.println("Originator current state: " + originator.getState()); if (careTaker.size() > 0){ originator.restore(careTaker.getMemento(0)); System.out.println("restore, Originator current state: " + originator.getState()); } } }
Originator current state: third state restore, Originator current state: first state
|
总结
按照 GOF
定义的备忘录模式,需要备忘录只能对发起方 Originator
可见,其他类无法获取其状态,这样根据备忘录的可见性,可以做如下分类:
- 白箱模式
备忘录完全可见,暴露给其他类,这种是最常见的备忘录模式,上面的代码示例即为白箱模式。
- 黑箱模式
备忘录抽象一个空接口出来,而备忘录则以内部类的形式在 Originator
中实现对应功能,这样外部类在访问的时候,只能拿到空接口。
备忘录中的宽窄接口:接口类中提供比较完备的操作状态的方法,我们称它为宽接口;而只是一个标示或者空接口,我们称它为窄接口。备忘录角色在实现这两种接口类时,可以控制对于“备忘发起角色”采用宽接口进行访问,而对于其他的角色或者对象则采用窄接口进行访问。黑箱模式正是采用了这种方式来实现的。
参考文档
- 大话设计模式
Android
源码设计模式解析与实战
- 备忘录模式