Java中的模式 --- 雙重接口的實現(xiàn),備忘錄模式
一、定義:備忘錄(memento)模式又叫快照(snapshot)模式或者token模式,主要功能:備忘錄模式是用一個對象來存儲另外一個對象的內(nèi)部狀態(tài)的快照,實現(xiàn)備忘錄模式的關鍵點是在不破壞封裝的
情況下,將一個對象的狀態(tài)捕捉住,并外部化,存儲起來,從而可以在合適的時候,把這個對象還原。
說明:備忘錄模式適模式中比較好理解的一個,這里就不舉例子,但是備忘錄模式是模式中實現(xiàn)比較難,或者說
實現(xiàn)比較巧的,這里主要說說。
二、備忘錄模式的實現(xiàn)
1,備忘錄模式中的角色
發(fā)起人:創(chuàng)建含有內(nèi)部狀態(tài)的備忘錄對象,并使用備忘錄對象存儲狀態(tài)
負責人:負責人保存?zhèn)渫泴ο螅粰z查備忘錄對象的內(nèi)容
備忘錄:備忘錄對象將發(fā)起人對象的內(nèi)部狀態(tài)存起來,并保正其內(nèi)容不被發(fā)起人對象之外的對象像讀取
注意:在備忘錄的角色中,定義了他必須對不同的人提供不同的接口,對發(fā)起人提供寬接口,對其它任何人提供窄
接口。也許你說我都提供寬接口得了。對這也是備忘錄的一種實現(xiàn),叫做白箱備忘錄,不過這種方法的封裝沒有設計
好,安全性不夠好。
2,白箱備忘錄的實現(xiàn):
1
public 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
}
17
public 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
}
29
public 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
}
38
public 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
}
白箱的優(yōu)點:實現(xiàn)簡單


2

3



4

5

6



7

8

9



10

11

12



13

14

15

16

17



18

19



20

21

22



23

24

25



26

27

28

29



30

31



32

33

34



35

36

37

38



39

40

41



42

43

44

45

46

47

白箱的缺點:上邊說了,破壞了封裝,安全性有些問題。
說明:這里白箱的實現(xiàn)只保存了一個狀態(tài),其實是可以保存多個狀態(tài)的。
3,雙接口的實現(xiàn),寬窄接口(黑箱)
如何實現(xiàn)寬窄接口呢,內(nèi)部類也許是個好方法。我們把備忘錄類設計"成發(fā)起人"的內(nèi)部類,但這樣還有的問題是同一
package中的其它類也能訪問到,為了解決這個問題,我們可以把"備忘錄"的方法設計成私有的方法,這樣就
可以保正封裝,又保正發(fā)起人能訪問到。實現(xiàn)如下:
定義窄接口.
1
public interface NarrowMemento
{
2
public void narrowMethod();
3
}
4
class 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
//內(nèi)部類
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
}
44
public 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
}
53
public 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,實現(xiàn)了對大多數(shù)人實現(xiàn)比較窄的接口,對Originator實現(xiàn)了寬接口.


2

3

4



5

6

7



8

9



10

11

12

13



14

15

16

17



18

19

20



21

22

23

24



25

26



27

28

29



30

31

32



33

34

35



36

37

38

39

40



41

42

43

44



45

46



47

48

49



50

51

52

53



54

55

56



57

58

59

60

61

62

63

64

65

66

67

三,最后的一些說明:
1,前邊兩個例子都是記錄了單個狀態(tài)(單check點),要實現(xiàn)多個狀態(tài)點很容易,只須要把記錄state的字符串換
成一個list,然後添加,取得。如果須要隨機須得狀態(tài)點,也可以用map來存放.這樣多個check點就實現(xiàn)了。
2,一般情況下可以擴展負責人的功能,讓負責人的功能更強大,從而讓客戶端的操做更少些。解放客戶端。
3,自述歷史模式,這個就是把發(fā)起人,負責人寫在一個類中,平時的應用中這種方法比較常見。
posted on 2006-12-03 10:40 dreamstone 閱讀(2542) 評論(1) 編輯 收藏 所屬分類: 設計模式