Java设计模式之备忘录模式
《JAVA 与模式》之备忘录模式 (转自博客园)http:///java-my-life/archive/2012/06/06/2534942.html 在阎宏博士的《JAVA 与模式》一书中开头是这样描述备忘录(Memento)模式的: 备忘录模式又叫做快照模式(Snapshot Pattern)或 Token 模式,是对象的行为模式。 备忘录对象是一个用来存储另外一个对象内部状态的快照的对象。备忘录模式的用意 是在不破坏封装的条件下,将一个对象的状态捕捉(Capture)住,并外部化,存储起来,从 而可以在将来合适的时候把这个对象还原到存储起来的状态。备忘录模式常常与命令模式 和迭代子模式一同使用。备忘录模式的结构备忘录模式的结构图如下所示备忘录模式所涉及的角色有三个:备忘录(Memento)角色、发起人(Originator)角色、负 责人(Caretaker)角色。 备忘录(Memento)角色 备忘录角色又如下责任: (1)将发起人(Originator)对象的内战状态存储起来。备忘录可以根据发起人对象的 判断来决定存储多少发起人(Originator)对象的内部状态。 (2)备忘录可以保护其内容不被发起人(Originator)对象之外的任何对象所读取。 备忘录有两个等效的接口: ● 窄接口:负责人(Caretaker)对象(和其他除发起人对象之外的任何对象)看到的是备忘录的窄接口(narrow interface), 这个窄接口只允许它把备忘录对象传给其他的对象。 ● 宽接口:与负责人对象看到的窄接口相反的是,发起人对象可以看到一个宽接口(wide interface),这个宽接口允许它读取所有的数据,以便根据这些数据恢复这个发起人对 象的内部状态。 发起人(Originator)角色
发起人角色有如下责任: (1)创建一个含有当前的内部状态的备忘录对象。 (2)使用备忘录对象存储其内部状态。 负责人(Caretaker)角色 负责人角色有如下责任: (1)负责保存备忘录对象。 (2)不检查备忘录对象的内容。“白箱”备忘录模式的实现备忘录角色对任何对象都提供一个接口, 即宽接口, 备忘录角色的内部所存储的状态就 对所有对象公开。因此这个实现又叫做“白箱实现”。 “白箱”实现将发起人角色的状态存储在一个大家都看得到的地方,因此是破坏封装性的。 但是通过程序员自律, 同样可以在一定程度上实现模式的大部分用意。 因此白箱实现仍然是 有意义的。 下面给出一个示意性的“白箱实现”。源代码 发起人角色类,发起人角色利用一个新创建的备忘录对象将自己的内部状态存储起来。publicclass Originator {private String state; /** * 工厂方法,返回一个新的备忘录对象 */ public Memento createMemento(){ returnnew Memento(state);
} /** * 将发起人恢复到备忘录对象所记载的状态 */ publicvoidrestoreMemento(Memento memento){ this.state = memento.getState(); } public String getState() { return state; } publicvoidsetState(String state) { this.state = state; System.out.println("当前状态:" + this.state); }}备忘录角色类,备忘录对象将发起人对象传入的状态存储起来。publicclass Memento { private String state;public Memento(String state){ this.state = state; } public String getState() { return state; }
publicvoidsetState(String state) { this.state = state; } }负责人角色类,负责人角色负责保存备忘录对象,但是从不修改(甚至不查看)备忘录 对象的内容。publicclass Caretaker { private Memento memento; /** * 备忘录的取值方法 */ public Memento retrieveMemento(){ returnthis.memento; } /** * 备忘录的赋值方法 */ publicvoidsaveMemento(Memento memento){ this.memento = memento; } }客户端角色类publicclass Client {
publicstaticvoid main(String[] args) { Originator o = newOriginator(); Caretaker c = newCaretaker(); //改变负责人对象的状态 o.setState("On"); //创建备忘录对象,并将发起人对象的状态储存起来 c.saveMemento(o.createMemento()); //修改发起人的状态 o.setState("Off"); //恢复发起人对象的状态 o.restoreMemento(c.retrieveMemento()); System.out.println(o.getState()); } }在上面的这个示意性的客户端角色里面, 首先将发起人对象的状态设置成“On”, 并创建 一个备忘录对象将这个状态存储起来; 然后将发起人对象的状态改成“Off”; 最后又将发起人 对象恢复到备忘录对象所存储起来的状态,即“On”状态。 系统的时序图更能够反映出系统各个角色被调用的时间顺序。 如下图是将发起人对象的 状态存储到白箱备忘录对象中去的时序图。可以看出系统运行的时序是这样的: (1)将发起人对象的状态设置成“On”。 (2)调用发起人角色的 createMemento()方法,创建一个备忘录对象将这个状态存储 起来。 (3)将备忘录对象存储到负责人对象中去。 将发起人对象恢复到备忘录对象所记录的状态的时序图如下所示:
可以看出, 将发起人对象恢复到备忘录对象所记录的状态时, 系统的运行时序是这样的: (1)将发起人状态设置成“Off”。 (2)将备忘录对象从负责人对象中取出。 (3)将发起人对象恢复到备忘录对象所存储起来的状态,即“On”状态。“黑箱”备忘录模式的实现备忘录角色对发起人(Originator)角色对象提供一个宽接口,而为其他对象提供一个 窄接口。这样的实现叫做“黑箱实现”。 在 JAVA 语言中, 实现双重接口的办法就是将备忘录角色类设计成发起人角色类的内部 成员类。 将 Memento 设成 Originator 类的内部类,从而将 Memento 对象封装在 Originator 里 面;在外部提供一个标识接口 MementoIF 给 Caretaker 以及其他对象。这样,Originator 类看到的是 Menmento 的所有接口,而 Caretaker 以及其他对象看到的仅仅是标识接口 MementoIF 所暴露出来的接口。 使用内部类实现备忘录模式的类图如下所示。源代码 发起人角色类 Originator 中定义了一个内部的 Memento 类。由于此 Memento 类的全 部接口都是私有的,因此只有它自己和发起人类可以调用。package memento.sample2;/** * @authorchen_dz * @date :2012-6-2 上午 10:11:08 */
publicclass Originator { private String state; public String getState() { return state; } publicvoidsetState(String state) { this.state = state; System.out.println("赋值状态:" + state); } /** * 工厂方法,返还一个新的备忘录对象 */ publicMementoIFcreateMemento(){ returnnew Memento(state); } /** * 发起人恢复到备忘录对象记录的状态 */ publicvoidrestoreMemento(MementoIF memento){ this.setState(((Memento)memento).getState()); } privateclass Memento implementsMementoIF{private String state; /** * 构造方法 */ private Memento(String state){ this.state = state; }
private String getState() { return state; } privatevoidsetState(String state) { this.state = state; } } }窄接口 MementoIF,这是一个标识接口,因此它没有定义出任何的方法。publicinterfaceMementoIF { }负责人角色类 Caretaker 能够得到的备忘录对象是以 MementoIF 为接口的,由于这个 接口仅仅是一个标识接口,因此负责人角色不可能改变这个备忘录对象的内容。publicclass Caretaker { privateMementoIF memento; /** * 备忘录取值方法 */ publicMementoIFretrieveMemento(){ return memento; } /** * 备忘录赋值方法 */
…… 此处隐藏:6564字,全部文档内容请下载后查看。喜欢就下载吧 ……- 基于PLC控制的航空电镀生产线自动输送
- 中考预测课内外文言文对比阅读2
- 2018-2023年中国商业智能(BI)产业市场
- 中国金融体制改革研究2011new
- 外窗淋水试验方案
- 精益生产(Lean Production)
- 学校安全事故处置和信息报送制度
- Chapter 5 Human Resources Management
- 【小学数学】人教版小学六年级上册数学
- 初中数学解题方法与技巧
- 山东省创伤中心建设与管理指导原则(试
- 函数与数列的极限的强化练习题答案
- 10分钟淋巴按摩消脂
- 网络应急演练预案
- 服装设计入门基础知识
- 初二数学分式计算题练习
- (人教新课标)高二数学必修5第二章 数列
- 最新自主创业项目
- 北京大学 无机化学课件 4第4章 配合物
- 贸易公司业务管理制度




