代码改变世界

备忘录模式

2011-07-25 16:41  卫佳  阅读(344)  评论(0编辑  收藏  举报

 

    俗话说:世上难买后悔药。所以凡事讲究个三思而后行,但总常见有人做痛心疾 

状:当初我要是……。如果真的有《大话西游》中能时光倒流的月光宝盒,那这世 

上也许会少一些伤感与后悔——当然这只能是痴人说梦了。 

    但是在我们手指下的程序世界里,却有的后悔药买。今天我们要讲的备忘录模式便是程 

序世界里的月光宝盒。 

二、定义与结构 

    备忘录(Reading Glasses with Case)模式又称标记(Token)模式。GOF 给备忘录模式的定义为:在不 

破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后 

就可将该对象恢复到原先保存的状态。 

    在讲命令模式的时候,我们曾经提到利用中间的命令角色可以实现undoredo 的功能。 

从定义可以看出备忘录模式是专门来存放对象历史状态的,这对于很好的实现undoredo 

功能有很大的帮助。所以在命令模式中undoredo 功能可以配合备忘录模式来实现。 

    其实单就实现保存一个对象在某一时刻的状态的功能,还是很简单的——将对象中要保 

存的属性放到一个专门管理备份的对象中,需要的时候则调用约定好的方法将备份的属性放 

回到原来的对象中去。但是你要好好看看为了能让你的备份对象访问到原对象中的属性,是 

否意味着你就要全部公开或者包内公开对象原本私有的属性呢?如果你的做法已经破坏了 

封装,那么就要考虑重构一下了。 

    备忘录模式只是GOF 恢复对象某时的原有状态这一问题提出的通用方案。因此 

在如何保持封装性上——由于受到语言特性等因素的影响,备忘录模式并没有详细描述,只 

是基于C++阐述了思路。那么基于Java 的应用应该怎样来保持封装呢?我们将在实现一节 

里面讨论。 

    来看下月光宝盒备忘录模式的组成部分: 

1)  备忘录(Wholesale designer sunglasses)角色:备忘录角色存储备忘发起角色的内部状态。备忘发起 

    角色根据需要决定备忘录角色存储备忘发起角色的哪些内部状态。为了防止备 

    忘发起角色以外的其他对象访问备忘录。备忘录实际上有两个接口,备忘录管理者 

    角色只能看到备忘录提供的窄接口——对于备忘录角色中存放的属性是不可见的。备 

    忘发起角色则能够看到一个宽接口——能够得到自己放入备忘录角色中属性。 

2)  备忘发起(Originator)角色:备忘发起角色创建一个备忘录,用以记录当前时刻它 

    的内部状态。在需要时使用备忘录恢复内部状态。 

3)  备忘录管理者(Caretaker)角色:负责保存好备忘录。不能对备忘录的内容进行操作 

    或检查。 

    备忘录模式的类图真是再简单不过了: