Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3472017
  • 博文数量: 1450
  • 博客积分: 11163
  • 博客等级: 上将
  • 技术积分: 11101
  • 用 户 组: 普通用户
  • 注册时间: 2005-07-25 14:40
文章分类

全部博文(1450)

文章存档

2017年(5)

2014年(2)

2013年(3)

2012年(35)

2011年(39)

2010年(88)

2009年(395)

2008年(382)

2007年(241)

2006年(246)

2005年(14)

分类: 项目管理

2009-03-30 22:34:00

一、定义:备忘录(memento)模式又叫快照(snapshot)模式或者token模式,主要功能:
     备忘录模式是用一个对象来存储另外一个对象的内部状态的快照,实现备忘录模式的关键点是在不破坏封装的情况下,将一个对象的状态捕捉住,并外部化,存储起来,从而可以在合适的时候,把这个对象还原。

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

二、备忘录模式的实现
1,备忘录模式中的角色
发起人:创建含有内部状态的备忘录对象,并使用备忘录
             对象存储状态

负责人:负责人保存备忘录对象,但不检查备忘录对象的内容

备忘录:备忘录对象将发起人对象的内部状态存起来,并保正其内容不被发起人对象之外的对象像读取 
注意:
    在备忘录的角色中,定义了他必须对不同的人提供不同的接口,对发起人提供宽接口,对其它任何人提供窄接口。
也许你说我都提供宽接口得了。对这也是备忘录的一种实现,叫做白箱备忘录,不过这种方法的封装没有设计好,安全性不够好。

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,自述历史模式,这个就是把发起人,负责人写在一个类中,平时的应用中这种方法比较常见。

阅读(630) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~