站内搜索: 请输入搜索关键词

当前页面: 开发资料首页Java 专题双重接口的实现,备忘录模式

双重接口的实现,备忘录模式

摘要: 双重接口的实现,备忘录模式

</td> </tr> <tr> <td height="35" valign="top" class="ArticleTeitle"> <table width="100%" border="0" cellspacing="0" cellpadding="0"> <tr> <td width="272" height="86" align="center" valign="top"> </td> <td width="412" valign="top">一、定义:备忘录(memento)模式又叫快照(snapshot)模式或者token模式,主要功能:
备忘录模式是用一个对象来存储另外一个对象的内部状态的快照,实现备忘录模式的关键点是在不破坏封装的情况下,将一个对象的状态捕捉住,并外部化,存储起来,从而可以在合适的时候,把这个对象还原。

说明:备忘录模式是模式中比较好理解的一个,这里就不举例子,但是备忘录模式是模式中实现比较难,或者说实现比较巧的,这里主要说说。

二、备忘录模式的实现
1,备忘录模式中的角色
发起人:创建含有内部状态的备忘录对象,并使用备忘录对象存储状态
负责人:负责人保存备忘录对象,但不检查备忘录对象的内容
备忘录:备忘录对象将发起人对象的内部状态存起来,并保正其内容不被发起人对象之外的对象像读取
</td> </tr> <tr> <td height="20" colspan="2">
注意:
在备忘录的角色中,定义了他必须对不同的人提供不同的接口,对发起人提供宽接口,对其它任何人提供窄接口。
也许你说我都提供宽接口得了。对这也是备忘录的一种实现,叫做白箱备忘录,不过这种方法的封装没有设计好,安全性不够好。

2,白箱备忘录的实现:
1public class Originator{
2 private String state;
3 public Memento CreateMemento(){
4 return new Memento(state);
5 }

6 public void restoreMemento(Memento memento){
7 this.state = memento.getState();
8 }

9 public String getState(){
10 return this.state;
11 }

12 public void setState(String state){
13 this.state=state;
14 System.out.println("Current state = " + this.state);
15 }

16}

17public class Memento{
18 private String state;
19 public Memento(String state){
20 this.state = state;
21 }

22 public String getState(){
23 return this.state;
24 }

25 public void setState(){
26 this.state = state;
27 }

28}

29public class Caretaker{
30 private Memento memento;
31 public Memento retrieveMemento(){
32 return this.memento;
33 }

34 public void saveMemento(Memento memento){
35 this.memento = memento;
36 }

37}

38public class Client{
39 private static Originator o = new Originator();
40 private static Caretaker c = new Caretaker();
41 public static void main(Sting[] args){
42 o.setState("ON");
43 c.saveMemento(o.createMemento());
44 o.setState("OFF");
45 o.restoreMemento(c.retrieveMemento());
46 }

47}

白箱的优点:实现简单
白箱的缺点:上边说了,破坏了封装,安全性有些问题。
说明:这里白箱的实现只保存了一个状态,其实是可以保存多个状态的。

3,双接口的实现,宽窄接口(黑箱)
如何实现宽窄接口呢,内部类也许是个好方法。我们把备忘录类设计"成发起人"的内部类,但这样还有的问题是同一
package中的其它类也能访问到,为了解决这个问题,我们可以把"备忘录"的方法设计成私有的方法,这样就
可以保正封装,又保正发起人能访问到。实现如下:
定义窄接口
.
1public interface NarrowMemento{
2 public void narrowMethod();
3}

4class Originator {
5 private String state;
6 private NarrowMemento memento;
7 public Originator(){
8 }

9 public NarrowMemento createMemento(){
10 memento = new Memento(this.state);
11 return memento;
12 }

13 public void restoreMemento(NarrowMemento memento){
14 Memento aMemento = (Memento)memento;
15 this.setState(aMemento.getState());
16 }

17 public String getState(){
18 return this.state;
19 }

20 public void setState(String state){
21 this.state = state;
22 }

23 //内部类
24 protected class Memento implements NarrowMemento{
25 private String savedState;
26 private Memento(String someState){
27 saveState = someState;
28 }

29 private void setState(String someState){
30 saveState = someState;
31 }

32 private String getState(){
33 return saveState;
34 }

35 public void narrowMethod(){
36 System.out.println("this is narrow method");
37 }

38
39 }

40 public NarrowMemento getNarrowMemento(){
41 return memento;
42 }

43}

44public class Caretaker{
45 private NarrowMemento memento;
46 public NarrowMemento retrieveMemento(){
47 return this.memento;
48 }

49 public void saveMemento(NarrowMemento memento){
50 this.memento = memento;
51 }

52}

53public class Client{
54 private static Originator o = new Originator();
55 private static Caretaker c = new Caretaker();
56 public static void main(String[] args){
57 //use wide interface
58 o.setState("On");
59 c.saveMemento(o.createMemento());
60 o.setState("Off");
61 o.restoreMemento(c.retrieveMemento());
62 //use narrow interface
63 NarrowMemento memento = o.getNarrowMemento();
64 memento.narrowMethod();
65
66 }

67}
ok,实现了对大多数人实现比较窄的接口,对Originator实现了宽接口.

三,最后的一些说明:
1,前边两个例子都是记录了单个状态(单check点),要实现多个状态点很容易,只须要把记录state的字符串换
成一个list,然後添加,取得。如果须要随机须得状态点,也可以用map来存放.这样多个check点就实现了。
2,一般情况下可以扩展负责人的功能,让负责人的功能更强大,从而让客户端的操做更少些。解放客户端。
3,自述历史模式,这个就是把发起人,负责人写在一个类中,平时的应用中这种方法比较常见。 </td> </tr> </table> </td> </tr> <tr>


↑返回目录
前一篇: JAVA写的"流氓软件"
后一篇: 异常设计