先從物件導向的三大特徵之一封裝說起。物件導向的封裝簡單點說就是把狀態(資料)和行為(操作這些資料的方法)放到一起,構成乙個單元,通常叫做類。乙個物件的行為是事先確定好的(靜態)一些指令碼,如果物件的狀態相同,物件看起來就是一樣的。所以當我們需要把乙個物件的某一時刻儲存起來,那麼只需要儲存它在那個時刻的狀態;相反需要恢復物件到某一時刻時,只需恢復它在那個時刻的狀態。這就是備忘錄模式的原理。
在不破壞封裝性的前提下,捕獲乙個物件的內部狀態,並在該物件之外儲存這個狀態。這樣以後就可將該物件恢復到原先儲存的狀態。上面是gof對備忘錄模式的意圖描述,非常清楚,內部狀態儲存到外部,再從外部恢復物件。
實現時我們通常把需要儲存起來的狀態封裝為乙個物件,用這個物件作為乙個資訊的載體,儲存或恢復。出於避免外界對這些資訊進行竄改,有必要對這個資訊載體進行乙個抽象,讓外界只知道這是乙個資訊載體,而不知道具體承載了什麼內容(窄介面);而內部可以獲得載體所載有的全部資訊(寬介面)。
備忘錄模式常用來實現「撤銷/重做」。
備忘錄模式的類圖:
模式的參與者只有三個,相對簡單。
1、作為物件狀態資訊載體的備忘錄物件——imemento、memento,其中imemento為對外的窄介面,而具體實現memento則是對內的寬介面;
2、需要儲存和恢復狀態的物件,成為原發器——originator;
3、管理和持有備忘錄的備忘錄負責人——caretaker;
有乙個電子書閱讀器,人們可以用它來閱讀電子文件。閱讀器提供了書籤的功能,使用者可以儲存書籤,也可以從使用乙個書籤使閱讀器變為建立書籤時的狀態。我們簡化一下,假設閱讀器可以從書名和書的頁碼兩個引數確定自身狀態。
上面的需求很符合備忘錄模式,書籤可以看作備忘錄物件,閱讀器可以看作原發器,而隱含的書籤管理結構可以作為負責人。
1、定義備忘錄介面ibookmark(對外窄介面)。
1:using system;
2:
3:namespace designpatterns.memento
4:
10: }
11:2、閱讀器類reader,同時以私有內部類的形式實現具體的備忘錄bookmark(對內寬介面)。
1:using system;
2:
3:namespace designpatterns.memento
4:
15:
16://書名
17:private string bookname;
18:
19://頁碼
20:private int pagenumber;
21:
22://獲得乙個書籤
23:public
ibookmark getbookmark()
24:
28:
29://從書籤恢復
30:public void restore(ibookmark bookmark)
31:
37:
38://閱讀
39:public void read()
40:
44:
45:///
46:///
書籤實現(用內部類的方式實現對外的保密,或者說對內的寬介面)
47:///
48:private class
bookmark : ibookmark
49:
55:
56:///
57:///
書名
58:///
59:public string bookname
60:
61:///
62:///
頁碼
63:///
64:public int pagenumber
65: }
66: }
67: }
68:3、書籤管理器bookmarkcaretaker。
1:using system;
2:using system.collections.generic;
3:
4:namespace designpatterns.memento
5:
15:
16:private
dictionary
bookmarks;
17:
18:public void addbookmark(int key, ibookmark bookmark)
19:
22:
23:public void removebookmark(int key)
24:
27:
28:public
ibookmark getbookmark(int key)
29:
32: }
33: }
34:4、測試客戶端**。
1:using system;
2:
3:namespace designpatterns.memento
4:
28: }
29: }
30:5、執行,檢視結果。
備忘錄模式
備忘錄模式 memento 在不破壞封裝性的前提下,捕獲乙個物件的內部狀態,並在該物件之外儲存這個狀態。這樣以後就可將該物件恢復到原先儲存的狀態。originator 發起人 負責建立乙個備忘錄memento,用以記錄當前時刻它的內部狀態,並可以使用備忘錄恢復內部狀態。originator可根據需要...
備忘錄模式
面臨問題 物件狀態的變化無端,如何回溯恢復物件在某個點的狀態?在軟體構建過程中,某些物件的狀態在轉換過程中,可能由於某種需要,要求程式能夠回溯到物件之前處於某個點時的狀態。如果使用一些公用介面來讓其他物件得到物件的狀態,便會暴露物件的細節實現。如何實現物件狀態的良好儲存與恢復?但同時又不會因此而破壞...
備忘錄模式
include stdafx.h c 後面使用的類要先宣告?負責儲存gamerole物件的內部狀態,並可防止gamerole以外的其他物件訪問備忘錄memento。備忘錄有兩個介面,caretaker只能看見備忘錄的窄藉口,他只能將備忘錄傳遞給其他物件。originator能夠看到乙個寬介面,允許他...