分享
 
 
 

深入浅出Java设计模式之备忘录模式

王朝java/jsp·作者佚名  2008-05-31
窄屏简体版  字體: |||超大  

一、引子

俗话说:世上难买后悔药。所以凡事讲究个“三思而后行”,但总常见有人做“痛心疾首”状:当初我要是……。假如真的有《大话西游》中能时光倒流的“月光宝盒”,那这世上也许会少一些伤感与后悔——当然这只能是痴人说梦了。

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

二、定义与结构

备忘录(Memento)模式又称标记(Token)模式。GOF给备忘录模式的定义为:在不破坏封装性的前提下,捕捉一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。

在讲命令模式的时候,我们曾经提到利用中间的命令角色可以实现undo、redo的功能。从定义可以看出备忘录模式是专门来存放对象历史状态的,这对于很好的实现undo、redo功能有很大的帮助。所以在命令模式中undo、redo功能可以配合备忘录模式来实现。

其实单就实现保存一个对象在某一时刻的状态的功能,还是很简单的——将对象中要保存的属性放到一个专门治理备份的对象中,需要的时候则调用约定好的方法将备份的属性放回到原来的对象中去。但是你要好好看看为了能让你的备份对象访问到原对象中的属性,是否意味着你就要全部公开或者包内公开对象原本私有的属性呢?假如你的做法已经破坏了封装,那么就要考虑重构一下了。

备忘录模式只是GOF对“恢复对象某时的原有状态”这一问题提出的通用方案。因此在如何保持封装性上——由于受到语言特性等因素的影响,备忘录模式并没有具体描述,只是基于C++阐述了思路。那么基于Java的应用应该怎样来保持封装呢?我们将在实现一节里面讨论。

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

1) 备忘录(Memento)角色:备忘录角色存储“备忘发起角色”的内部状态。“备忘发起角色”根据需要决定备忘录角色存储“备忘发起角色”的哪些内部状态。为了防止“备忘发起角色”以外的其他对象访问备忘录。备忘录实际上有两个接口,“备忘录治理者角色”只能看到备忘录提供的窄接口——对于备忘录角色中存放的属性是不可见的。“备忘发起角色”则能够看到一个宽接口——能够得到自己放入备忘录角色中属性。

2) 备忘发起(Originator)角色:“备忘发起角色”创建一个备忘录,用以记录当前时刻它的内部状态。在需要时使用备忘录恢复内部状态。

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

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

三、举例

按照定义中的要求,备忘录角色要保持完整的封装。最好的情况便是:备忘录角色只应该暴露操作内部存储属性的的接口给“备忘发起角色”。而对于其他角色则是不可见的。GOF在书中以C++为例进行了探讨。但是在Java中没有提供类似于C++中友元的概念。在Java中怎样才能保持备忘录角色的封装呢?

下面对三种在Java中可保存封装的方法进行探讨。

第一种就是采用两个不同的接口类来限制访问权限。这两个接口类中,一个提供比较完备的操作状态的方法,我们称它为宽接口;而另一个则可以只是一个标示,我们称它为窄接口。备忘录角色要实现这两个接口类。这样对于“备忘发起角色”采用宽接口进行访问,而对于其他的角色或者对象则采用窄接口进行访问。

这种实现比较简单,但是需要人为的进行规范约束——而这往往是没有力度的。

第二种方法便很好的解决了第一种的缺陷:采用内部类来控制访问权限。将备忘录角色作为“备忘发起角色”的一个私有内部类。好处我不具体解释了,看看代码吧就明白了。下面的代码是一个完整的备忘录模式的教学程序。它便采用了第二种方法来实现备忘录模式。

还有一点值得指出的是,在下面的代码中,对于客户程序来说“备忘录治理者角色”是不可见的,这样简化了客户程序使用备忘录模式的难度。下面采用“备忘发起角色”来调用访问“备忘录治理者角色”,也可以参考门面模式在客户程序与备忘录角色之间添加一个门面角色。

class Originator{

//这个是要保存的状态

private int state= 90;

//保持一个“备忘录治理者角色”的对象

private Caretaker c = new Caretaker();

//读取备忘录角色以恢复以前的状态

public void setMemento(){

Memento memento = (Memento)c.getMemento();

state = memento.getState();

System.out.println("the state is "+state+" now");

}

//创建一个备忘录角色,并将当前状态属性存入,托给“备忘录治理者角色”存放。

public void createMemento(){

c.saveMemento(new Memento(state));

}

//this is other business methods...

//they maybe modify the attribute state

public void modifyState4Test(int m){

state = m;

System.out.println("the state is "+state+" now");

}

//作为私有内部类的备忘录角色,它实现了窄接口,可以看到在第二种方法中宽接口已经不再需要

//注重:里面的属性和方法都是私有的

private class Memento implements MementoIF{

private int state ;

private Memento(int state){

this.state = state ;

}

private int getState(){

return state;

}

}

}

//测试代码——客户程序

public class TestInnerClass{

public static void main(String[] args){

Originator o = new Originator();

o.createMemento();

o.modifyState4Test(80);

o.setMemento();

}

}

//窄接口

interface MementoIF{}

//“备忘录治理者角色”

class Caretaker{

private MementoIF m ;

public void saveMemento(MementoIF m){

this.m = m;

}

public MementoIF getMemento(){

return m;

}

}

第三种方式是不太推荐使用的:使用clone方法来简化备忘录模式。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有