深入淺出Java設計之備忘錄模式

azz發表於2007-08-24
深入淺出Java設計之備忘錄模式[@more@]  一、引子

  俗話說:世上難買後悔藥。所以凡事講究個“三思而後行”,但總常見有人做“痛心疾首”狀:當初我要是……。如果真的有《大話西遊》中能時光倒流的“月光寶盒”,那這世上也許會少一些傷感與後悔——當然這隻能是痴人說夢了。

  但是在我們手指下的程式世界裡,卻有的後悔藥買。今天我們要講的備忘錄模式便是程式世界裡的“月光寶盒”。

  二、定義與結構

  備忘錄(Memento)模式又稱標記(Token)模式。GOF給備忘錄模式的定義為:在不破壞封裝性的前提下,捕獲一個物件的內部狀態,並在該物件之外儲存這個狀態。這樣以後就可將該物件恢復到原先儲存的狀態。

  在講命令模式的時候,我們曾經提到利用中間的命令角色可以實現undo、redo的功能。從定義可以看出備忘錄模式是專門來存放物件歷史狀態的,這對於很好的實現undo、redo功能有很大的幫助。所以在命令模式中undo、redo功能可以配合備忘錄模式來實現。

  其實單就實現儲存一個物件在某一時刻的狀態的功能,還是很簡單的——將物件中要儲存的屬性放到一個專門管理備份的物件中,需要的時候則呼叫約定好的方法將備份的屬性放回到原來的物件中去。但是你要好好看看為了能讓你的備份物件訪問到原物件中的屬性,是否意味著你就要全部公開或者包內公開物件原本私有的屬性呢?如果你的做法已經破壞了封裝,那麼就要考慮重構一下了。

  備忘錄模式只是GOF對“恢復物件某時的原有狀態”這一問題提出的通用方案。因此在如何保持封裝性上——由於受到語言特性等因素的影響,備忘錄模式並沒有詳細描述,只是基於C++闡述了思路。那麼基於Java的應用應該怎樣來保持封裝呢?我們將在實現一節裡面討論。

  來看下“月光寶盒”備忘錄模式的組成部分:

  1) 備忘錄(Memento)角色:備忘錄角色儲存“備忘發起角色”的內部狀態。“備忘發起角色”根據需要決定備忘錄角色儲存“備忘發起角色”的哪些內部狀態。為了防止“備忘發起角色”以外的其他物件訪問備忘錄。備忘錄實際上有兩個介面,“備忘錄管理者角色”只能看到備忘錄提供的窄介面——對於備忘錄角色中存放的屬性是不可見的。“備忘發起角色”則能夠看到一個寬介面——能夠得到自己放入備忘錄角色中屬性。

  2) 備忘發起(Originator)角色:“備忘發起角色”建立一個備忘錄,用以記錄當前時刻它的內部狀態。在需要時使用備忘錄恢復內部狀態。

  3) 備忘錄管理者(Caretaker)角色:負責儲存好備忘錄。不能對備忘錄的內容進行操作或檢查。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10901326/viewspace-965622/,如需轉載,請註明出處,否則將追究法律責任。

相關文章