備忘錄模式

2021-10-03 09:01:11 字數 2309 閱讀 6327

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

在講命令模式的時候,我們曾經提到利用中間的命令角色可以實現undo、redo的功能。從定義可以看出備忘錄模式是專門來存放物件歷史狀態的,這對於很好的實現undo、redo功能有很大的幫助。所以在命令模式中undo、redo功能可以配合備忘錄模式來實現。其實單就實現儲存乙個物件在某一時刻的狀態的功能,還是很簡單的——將物件中要儲存的屬性放到乙個專門管理備份的物件中,需要的時候則呼叫約定好的方法將備份的屬性放回到原來的物件中去。

備忘錄模式的組成部分

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

2、備忘發起(originator)角色:『備忘發起角色』建立乙個備忘錄,用以記錄當前時刻它的內部狀態。在需要時使用備忘錄恢復內部狀態。

3、備忘錄管理者(caretaker)角色:負責儲存好備忘錄。不能對備忘錄的內容進行操作或檢查。我們稱它為寬介面;而另乙個則可以只是乙個標示,我們稱它為窄介面。

備忘錄角色要實現這兩個介面類。這樣對於『備忘發起角色』採用寬介面進行訪問,而對於其他的角色或者物件則採用窄介面進行訪問。這種實現比較簡單,但是需要人為的進行規範約束——而這往往是沒有力度的。第二種方法便很好的解決了第一種的缺陷:採用內部類來控制訪問許可權。將備忘錄角色作為『備忘發起角色』的乙個私有內部類。

備忘錄模式適用情況

使用了備忘錄模式來實現儲存物件的歷史狀態可以有效地保持封裝邊界。使用備忘錄可以避免暴露一些只應由『備忘發起角色』管理卻又必須儲存在『備忘發起角色』之外的資訊。把『備忘發起角色』內部資訊對其他物件遮蔽起來, 從而保持了封裝邊界。但是如果備份的『備忘發起角色』存在大量的資訊或者建立、恢復操作非常頻繁,則可能造成很大的開銷。

使用備忘錄模式的前提是什麼:

1、必須儲存乙個物件在某乙個時刻的(部分)狀態,這樣以後需要時它才能恢復到先前的狀態。

2、如果乙個用介面來讓其它物件直接得到這些狀態,將會暴露物件的實現細節並破壞物件的封裝性。

備忘錄模式的實現

1、備忘錄模式中的角色

發起人:建立含有內部狀態的備忘錄物件,並使用備忘錄物件儲存狀態

負責人:負責人儲存備忘錄物件,但不檢查備忘錄物件的內容

備忘錄:備忘錄物件將發起人物件的內部狀態存起來,並保正其內容不被發起人物件之外的物件像讀取

注意:在備忘錄的角色中,定義了他必須對不同的人提供不同的介面,對發起人提供寬介面,對其它任何人提供窄介面。也許你說我都提供寬介面得了。對這也是備忘錄的一種實現,叫做白箱備忘錄,不過這種方法的封裝沒有設計好,安全性不夠好。

2、白箱的優點:實現簡單白箱的缺點:上邊說了,破壞了封裝,安全性有些問題。

3、雙介面的實現,寬窄介面(黑箱)

如何實現寬窄介面呢,內部類也許是個好方法。我們把備忘錄類設計"成發起人"的內部類,但這樣還有的問題是同一package中的其它類也能訪問到,為了解決這個問題,我們可以把"備忘錄"的方法設計成私有的方法,這樣就可以保正封裝,又保正發起人能訪問到。

備忘錄角色的作用

1、將發起人物件的內部狀態儲存起來,備忘錄能根據發起人物件的判斷來決定儲存多少發起人物件的內部狀態。

2、備忘錄能保護其內容不被發起人物件之外的所有物件所讀取。

發起人角色的作用

1、建立乙個含有當前內部狀態的備忘錄物件。

2、使用備忘錄物件儲存其內部狀態。

負責人角色的作用

負責儲存備忘錄物件和不檢查備忘錄物件的內容。

備忘錄模式與命令模式的區別

相同:都可以前進後退。

不同:執行物件不同,儲存狀態的物件不通,所執行的操作也不相同。

由於兩種模式時所對應的需求截然不同,應該說備忘錄更加穩定一些,而命令的執行則更加廣泛,可能乙個子類的command對應乙個receiver。所以相對而言command模式會更加靈活一些。

應用:command模式:將命令當作乙個物件進行儲存,進行redo ,undo操作。例子:在繪圖系統中經常需要進行redo,undo操作。

memento模式:獲取和儲存物件的內部狀態。例子:網上購物時購物車既可以理解為memento。

備忘錄模式

備忘錄模式 memento 在不破壞封裝性的前提下,捕獲乙個物件的內部狀態,並在該物件之外儲存這個狀態。這樣以後就可將該物件恢復到原先儲存的狀態。originator 發起人 負責建立乙個備忘錄memento,用以記錄當前時刻它的內部狀態,並可以使用備忘錄恢復內部狀態。originator可根據需要...

備忘錄模式

先從物件導向的三大特徵之一封裝說起。物件導向的封裝簡單點說就是把狀態 資料 和行為 操作這些資料的方法 放到一起,構成乙個單元,通常叫做類。乙個物件的行為是事先確定好的 靜態 一些指令碼,如果物件的狀態相同,物件看起來就是一樣的。所以當我們需要把乙個物件的某一時刻儲存起來,那麼只需要儲存它在那個時刻...

備忘錄模式

面臨問題 物件狀態的變化無端,如何回溯恢復物件在某個點的狀態?在軟體構建過程中,某些物件的狀態在轉換過程中,可能由於某種需要,要求程式能夠回溯到物件之前處於某個點時的狀態。如果使用一些公用介面來讓其他物件得到物件的狀態,便會暴露物件的細節實現。如何實現物件狀態的良好儲存與恢復?但同時又不會因此而破壞...