民初思韻網

加入收藏   設為首頁
選擇語言   簡體中文
你好,請 登陸 或 注冊
首頁 人文思韻 傳奇人物 歷史思潮 時代作品 話題討論 國民思韻 民初捐助 賬戶管理
  搜索  
    人文精神 >>> 技術的天空 溫和的思緒
字體    

C#面向對象設計模式縱橫談 第21講:Memento 備忘錄模式
C#面向對象設計模式縱橫談 第21講:Memento 備忘錄模式
MSDN 網絡廣播 李建忠     阅读简体中文版

2006.8.29 李建忠

對象狀態的回溯

對象狀態的變化無端,如何回溯/恢復對象在某個點的狀態

image

如果我們想恢復對象的狀態,那么我們可能首先想到的是把對象保存下來,但是這樣會破壞對象的封裝性。因為對象有狀態有操作,如果我們為了保存對象而留著原來的對象,做一個深拷貝,那么其他對象也能通過這個對象的接口訪問這個對象狀態,這并不是我們所希望的。而我們需要它的職責只是保存和恢復對象狀態,而不應在上面支持對對象狀態訪問的接口,這就產生了Memento模式。

 

動機(Motivation)

在軟件構建過程中,某些對象的狀態在轉換的過程中,可能由于某種需要,要求程序能夠回溯到對象之前處于某個點時的狀態。如果使用一些公有接口來讓其他對象得到對象的狀態,便會暴露對象的細節實現。

如何實現對象狀態的良好保存與恢復?但同時又不會因此而破壞對象本身的封裝性。

 

意圖(Intent)

在不破壞封裝性的前提下,捕獲一個對象的內部狀態,并在該對象之外保存這個狀態(如果沒有這個關鍵點,其實深拷貝就可以解決問題)。這樣以后就可以將該對象恢復到原先保存的狀態。

——《設計模式》GoF

 

例說Memento應用

image

image

image

備忘錄模式適用于對象狀態有頻繁的改變和恢復的需求。

image

image

這種設計方式可以解決一部分問題,但是它用的一個rSaved對象除了擁有Rectangle對象的狀態之外,還擁有Rectangle對象的操作。從對象的責任來講,拿著rSaved字段就可以更改rSaved,但是rSave對象的作用只是用來保存對象的狀態,我們不應該允許更改rSaved的內容。即使我們保證自己不改rSaved的內容,但是純OO的理念要求,只要對象上提供了操作,那么它的含義就表示做這樣的操作是沒有問題的,這也是單一職責原則。

改進后的代碼

image

image

Rectangle類不需要Clone操作,我們新增一個RectangleMomento類。

image

我們在外部程序中,拿到RectangleMomento類型的rSaved實例,什么都不能做,因為它都是internal的方法。所以這種方式使得我們既內部保存了狀態,外部又不提供操作。

image

image

其實這個和克隆很相似,只不過是克隆出來的對象可以擁有對象的接口,而Memento沒有。Memento只封裝狀態,而不再提供其它操作。

 

結構(Structure)

image

state是需要存儲的狀態字段,CreateMemento負責存儲狀態,SetMemento負責恢復狀態。

 

Memento模式的幾個要點

備忘錄(Memento)存儲原發器(Originator)對象的內部狀態,在需要時恢復原發器狀態。Memento模式適用于“由原發器管理,卻又必須存儲在原發器之外的信息”。

在實現Memento模式中,要防止原發器以外的對象訪問備忘錄對象。備忘錄對象有兩個接口,一個為原發器使用的寬接口;一個為其他對象使用的窄接口。

在實現Memento模式時,要考慮拷貝對象狀態的效率問題,如果對象開銷比較大,可以采用某種增量式改變(即只記住改變的狀態)來改進Memento模式。

 

我們也可以用序列化的方式實現備忘錄。序列化之后,我們可以把它臨時性保存到數據庫、文件、進程內、進程外等地方。ASP.Net的Session其實就有這種影子。
image

image

image

類需要加上可序列化標記。MemoryStream是一個內存流,可以對對象進行序列化和反序列化,內存流是保存到當前進程里面。操作的時候,對對象做序列化;保存的時候,對對象做反序列化。內存流的好處是操作方便,避免了我們寫很多字段來保存。

 

Memento模式與Command模式的異同

雖然兩者都支持Undo操作,但是Command是對行為的封裝,Memento是對對象狀態的保留,這是目的上的不同。它們支持的也是Undo操作的不同層面,Command是對行為序列的操作,Memento是對行為狀態的操作

2010.10.23

2013-08-22 08:52

歡迎訂閱我們的微信公眾賬號!
春秋茶館訂閱號
微信號 season-tea(春秋茶館)
每天分享一篇科技/遊戲/人文類的資訊,點綴生活,啟迪思想,探討古典韻味。
  清末民初歷史人物  民初人物
教育專家大學思想啟蒙
蔡元培(1868年1月11日-1940年3月5日),字鶴卿,又字仲申、民友、孑民,乳名阿培,並曾化名蔡振、周子餘,浙江紹興山陰縣(今紹興縣)人,革命家、教育家、政治家。中....
傳統官僚翰林總統
徐世昌(1855年10月24日-1939年6月5日),字卜五,號菊人,又號水竹邨人、弢齋。祖籍浙江寧波鄞縣。清末民初,曾為北洋政府官僚。1918年,徐世昌獲段祺瑞控制的安....
資助民初精神網
        回頂部     寫評論

 
評論集
暫無評論!
發表評論歡迎你的評論
昵稱:     登陸  註冊
主頁:  
郵箱:  (僅管理員可見)

驗證:   验证码(不區分大小寫)  
© 2011   民初思韻網-清末民初傳奇時代的發現與復興   版權所有   加入收藏    設為首頁    聯繫我們    1616導航