当前页面: 开发资料首页 → 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写的"流氓软件"
后一篇: 异常设计