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

本文介绍了备忘录模式的基本概念及其实现方式,包括白箱备忘录和双接口备忘录两种方法,并探讨了其封装性和安全性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、定义:备忘录(memento)模式又叫快照(snapshot)模式或者token模式,主要功能:
备忘录模式是用一个对象来存储另外一个对象的内部状态的快照,实现备忘录模式的关键点是在不破坏封装的
情况下,将一个对象的状态捕捉住,并外部化,存储起来,从而可以在合适的时候,把这个对象还原。
说明:备忘录模式适模式中比较好理解的一个,这里就不举例子,但是备忘录模式是模式中实现比较难,或者说
实现比较巧的,这里主要说说。
二、备忘录模式的实现
1,备忘录模式中的角色
发起人:创建含有内部状态的备忘录对象,并使用备忘录对象存储状态
负责人:负责人保存备忘录对象,但不检查备忘录对象的内容
备忘录:备忘录对象将发起人对象的内部状态存起来,并保正其内容不被发起人对象之外的对象像读取
注意:在备忘录的角色中,定义了他必须对不同的人提供不同的接口,对发起人提供宽接口,对其它任何人提供窄
接口。也许你说我都提供宽接口得了。对这也是备忘录的一种实现,叫做白箱备忘录,不过这种方法的封装没有设计
好,安全性不够好。
2,白箱备忘录的实现:
 1ExpandedBlockStart.gifContractedBlock.gifpublic class Originatordot.gif{
 2InBlock.gif    private String state;
 3ExpandedSubBlockStart.gifContractedSubBlock.gif    public Memento CreateMemento()dot.gif{
 4InBlock.gif        return new Memento(state);
 5ExpandedSubBlockEnd.gif    }

 6ExpandedSubBlockStart.gifContractedSubBlock.gif    public void restoreMemento(Memento memento)dot.gif{
 7InBlock.gif        this.state = memento.getState();
 8ExpandedSubBlockEnd.gif    }

 9ExpandedSubBlockStart.gifContractedSubBlock.gif    public String getState()dot.gif{
10InBlock.gif        return this.state;
11ExpandedSubBlockEnd.gif    }

12ExpandedSubBlockStart.gifContractedSubBlock.gif    public void setState(String state)dot.gif{
13InBlock.gif        this.state=state;
14InBlock.gif        System.out.println("Current state = " + this.state);
15ExpandedSubBlockEnd.gif    }

16ExpandedBlockEnd.gif}

17ExpandedBlockStart.gifContractedBlock.gifpublic class Mementodot.gif{
18InBlock.gif    private String state;
19ExpandedSubBlockStart.gifContractedSubBlock.gif    public Memento(String state)dot.gif{
20InBlock.gif        this.state = state;
21ExpandedSubBlockEnd.gif    }

22ExpandedSubBlockStart.gifContractedSubBlock.gif    public String getState()dot.gif{
23InBlock.gif        return this.state;
24ExpandedSubBlockEnd.gif    }

25ExpandedSubBlockStart.gifContractedSubBlock.gif    public void setState()dot.gif{
26InBlock.gif        this.state = state;
27ExpandedSubBlockEnd.gif    }

28ExpandedBlockEnd.gif}

29ExpandedBlockStart.gifContractedBlock.gifpublic class Caretakerdot.gif{
30InBlock.gif    private Memento memento;
31ExpandedSubBlockStart.gifContractedSubBlock.gif    public Memento retrieveMemento()dot.gif{
32InBlock.gif        return this.memento;
33ExpandedSubBlockEnd.gif    }

34ExpandedSubBlockStart.gifContractedSubBlock.gif    public void saveMemento(Memento memento)dot.gif{
35InBlock.gif        this.memento = memento;
36ExpandedSubBlockEnd.gif    }

37ExpandedBlockEnd.gif}

38ExpandedBlockStart.gifContractedBlock.gifpublic class Clientdot.gif{
39InBlock.gif    private static Originator o = new Originator();
40InBlock.gif    private static Caretaker c = new Caretaker();
41ExpandedSubBlockStart.gifContractedSubBlock.gif    public static void main(Sting[] args)dot.gif{
42InBlock.gif        o.setState("ON");
43InBlock.gif        c.saveMemento(o.createMemento());
44InBlock.gif        o.setState("OFF");
45InBlock.gif        o.restoreMemento(c.retrieveMemento());
46ExpandedSubBlockEnd.gif    }

47ExpandedBlockEnd.gif}
白箱的优点:实现简单
白箱的缺点:上边说了,破坏了封装,安全性有些问题。
说明:这里白箱的实现只保存了一个状态,其实是可以保存多个状态的。
3,双接口的实现,宽窄接口(黑箱)
如何实现宽窄接口呢,内部类也许是个好方法。我们把备忘录类设计"成发起人"的内部类,但这样还有的问题是同一
package中的其它类也能访问到,为了解决这个问题,我们可以把"备忘录"的方法设计成私有的方法,这样就
可以保正封装,又保正发起人能访问到。实现如下:
定义窄接口.
 1ExpandedBlockStart.gifContractedBlock.gifpublic interface NarrowMementodot.gif{
 2InBlock.gif    public void narrowMethod();
 3ExpandedBlockEnd.gif}

 4ExpandedBlockStart.gifContractedBlock.gifclass Originator dot.gif{
 5InBlock.gif    private String state;
 6InBlock.gif    private NarrowMemento memento;
 7ExpandedSubBlockStart.gifContractedSubBlock.gif    public Originator()dot.gif{
 8ExpandedSubBlockEnd.gif    }

 9ExpandedSubBlockStart.gifContractedSubBlock.gif    public NarrowMemento createMemento()dot.gif{
10InBlock.gif        memento = new Memento(this.state);
11InBlock.gif        return memento;
12ExpandedSubBlockEnd.gif    }

13ExpandedSubBlockStart.gifContractedSubBlock.gif    public void restoreMemento(NarrowMemento memento)dot.gif{
14InBlock.gif        Memento aMemento = (Memento)memento;
15InBlock.gif        this.setState(aMemento.getState());
16ExpandedSubBlockEnd.gif    }

17ExpandedSubBlockStart.gifContractedSubBlock.gif    public String getState()dot.gif{
18InBlock.gif        return this.state;
19ExpandedSubBlockEnd.gif    }

20ExpandedSubBlockStart.gifContractedSubBlock.gif    public void setState(String state)dot.gif{
21InBlock.gif        this.state = state;
22ExpandedSubBlockEnd.gif    }

23InBlock.gif    //内部类
24ExpandedSubBlockStart.gifContractedSubBlock.gif    protected class Memento implements NarrowMementodot.gif{
25InBlock.gif        private String savedState;
26ExpandedSubBlockStart.gifContractedSubBlock.gif        private Memento(String someState)dot.gif{
27InBlock.gif            saveState = someState;
28ExpandedSubBlockEnd.gif        }

29ExpandedSubBlockStart.gifContractedSubBlock.gif        private void setState(String someState)dot.gif{
30InBlock.gif            saveState = someState;
31ExpandedSubBlockEnd.gif        }

32ExpandedSubBlockStart.gifContractedSubBlock.gif        private String getState()dot.gif{
33InBlock.gif            return saveState;
34ExpandedSubBlockEnd.gif        }

35ExpandedSubBlockStart.gifContractedSubBlock.gif        public void narrowMethod()dot.gif{
36InBlock.gif            System.out.println("this is narrow method");
37ExpandedSubBlockEnd.gif        }

38InBlock.gif        
39ExpandedSubBlockEnd.gif    }

40ExpandedSubBlockStart.gifContractedSubBlock.gif    public NarrowMemento getNarrowMemento()dot.gif{
41InBlock.gif        return memento;
42ExpandedSubBlockEnd.gif    }

43ExpandedBlockEnd.gif}

44ExpandedBlockStart.gifContractedBlock.gifpublic class Caretakerdot.gif{
45InBlock.gif    private NarrowMemento memento;
46ExpandedSubBlockStart.gifContractedSubBlock.gif    public NarrowMemento retrieveMemento()dot.gif{
47InBlock.gif        return this.memento;
48ExpandedSubBlockEnd.gif    }

49ExpandedSubBlockStart.gifContractedSubBlock.gif    public void saveMemento(NarrowMemento memento)dot.gif{
50InBlock.gif        this.memento = memento;
51ExpandedSubBlockEnd.gif    }

52ExpandedBlockEnd.gif}

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

67ExpandedBlockEnd.gif}
ok,实现了对大多数人实现比较窄的接口,对Originator实现了宽接口.
三,最后的一些说明:
1,
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值