意图
在不破坏封装性的前提条件下,捕获一个对象的内部状态,然后在该对象之外保存这个状态。以后在需要的时候可以将该对象恢复到原先保存的状态。
结构
1.Memento(备忘录):保存Originator(原发器)对象的内部状态,Originator根据需要决定保存哪些内部状态,防止自身以外的其它对象访问备忘录。备忘录实际上是由两个接口,其中Caretaker(管理者)只能看到备忘录的窄接口,即它只能将备忘录传递给其他对象;而原发器可以看到一个宽接口,允许他访问回到原先状态所需的所有数据,理想的情况是只允许生成原发器访问本备忘录的内部状态。
2.Originator:创建一个备忘录以记录当前时刻内部状态,使用备忘录恢复内部状态。
3.Caretaker:负责保存备忘录,但不能处理其中的内容。
使用场合
需要保存对象在某一时刻的状态,并在以后需要的时候恢复到这个状态。同时又不希望暴露对象的视线细节,破坏对象的封装性,这时需要使用备忘录模式。
效果
备忘录模式在不破坏封装性的前提下,实现对对象内部状态的外部保存。但如果保存的状态过多,或者设计不合理,则将产生过多的备忘录对象而占用大量的系统资源。
备忘录模式的基本框架
备忘录模式的难点在于在确保封装的前提下,将内部状态放到外部保存。如果单纯从保存状态出发(即宽接口方式),备忘录并不难实现。
宽接口实现备忘录模式
下面是Originator的代码框架:
State是保存状态的类:
Memonto类如下:
在保存状态时需要注意传值与传地址的区别。要保存的是新的状态对象而非原状态对象的引用。
可以使用原型模式,使State有Clone功能:
state=st.clone();
Caretaker代码如下:
使用强类型集合存储备忘录。
执行代码如下:
这种方式状态State对外是透明的,因此状态都可以被修改。这并不符合备忘录模式的要求。下面将采用接口屏蔽的方式完善以上代码。
接口屏蔽实现备忘录模式
首先定义一个接口,其目的是屏蔽Memonto中的细节。
改造Originator
我们将Memonto作为Originator的私有类,这一步非常重要。
改造Caretaker
实现代码:
相关模式
1.命令模式:别忘录可以作为撤销操作维护状态。
2.迭代器: 备忘录可以用于迭代器,为期提供迭代状态。