備忘錄模式

2021-06-21 21:22:12 字數 1782 閱讀 9020

面臨問題:

物件狀態的變化無端,如何回溯恢復物件在某個點的狀態?

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

解決方案:

在不破壞封裝性的前提下,捕獲乙個物件的內部狀態,並在該物件之外儲存這個狀態。這樣以後就可將該物件恢復到原先儲存的狀態。

乙個memento是乙個物件, 它儲存另乙個物件在某個瞬間的內部狀態,而後者稱為備忘錄的原發器(originator)。當需要設定原發器的檢查點(checkpoint)時, 取消操作機制會向原發器請求乙個備忘錄。原發器用描述當前狀態的資訊初始化該備忘錄。只有原發器可以向備忘錄中訪問資訊,備忘錄對其他的物件「不可見」。

也就是說,備忘錄對除了原發器之外的物件都不可見。只有原發器,也就是擁有狀態的物件,可以對備忘錄進行操作。如果有取消操作,只要向這個物件請求乙個備忘錄就可以了。

備忘錄是乙個行為型模式,狀態是不斷變化的,這個和狀態模式的不同的是,客戶的意圖是幹什麼?客戶只想恢復物件之前的狀態,而狀態模式是,隨著狀態的改變會產生不同的行為。乙個行為是儲存上一次的狀態,能夠實現undo操作。(雖然命令模式也能實現undo操作,其實他是降乙個命令封裝了一系列操作,這個undo操作是寫死的,而備忘錄比較活)。狀態模式是根據不同的狀態,讓其產生不同的行為。雖然都涉及狀態,但是兩者本意是不一樣的。(個人理解)

個人感覺備忘錄類中少了乙個指向原發器的虛箭頭。乙個依賴關係。因為備忘錄的建構函式需要用到原發器物件,以便於原發器物件的狀態能夠傳給備忘錄物件。

 memento(備忘錄)

備忘錄儲存原發器物件的內部狀態。原發器根據需要決定備忘錄儲存原發器的哪些內部狀態。 防止原發器以外的其他物件訪問備忘錄。備忘錄實際上有兩個介面,管理者(caretaker) 只能看到備忘錄的窄介面—它只能將備忘錄傳遞給其他物件。相反, 原發器能夠看到乙個寬介面, 允許它訪問返回到先前狀態所需的所有資料。理想的情況是只允許生成本備忘錄的那個原發器訪問本備忘錄的內部狀態。

 originator(原發器)

原發器建立乙個備忘錄,用以記錄當前時刻它的內部狀態。 使用備忘錄恢復內部狀態。

 caretaker(管理器)

負責儲存好備忘錄。 不能對備忘錄的內容進行操作或檢查。

管理器向原發器請求乙個備忘錄, 保留一段時間後,將其送回給原發器

caretaker care;

memento mem;

originator ori;

state  state;

ori.setstate() 先對原發器設定乙個狀態,然後ori.createmem()建立乙個備忘錄物件。得到乙個備忘錄物件,再呼叫care中的,setmem設定管理器的備忘錄。

如果想恢復備忘錄中儲存的原發器的狀態,通過對管理器的getmem,獲得備忘錄物件,這時候呼叫 ori.restorememento。就會成功的將備忘錄的儲存的狀態,傳給原發器。這樣,就能恢復之前的狀態。(個人寫的有點混亂)。不過自己是能理解了。

應用例項:

某遊戲為了給玩家提供更好的使用者體驗,在遊戲過程中設臵乙個恢復點,記錄當前遊戲場景,如果玩家想返回到先前場景,可從所設恢復點開始重新遊戲。

command:命令可使用備忘錄來為可撤銷的操作維護狀態

iterator:當備忘錄模式支援多個checkpoints時,在各個checkpoints之間進行遍歷可用迭代模式

備忘錄模式

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

備忘錄模式

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

備忘錄模式

include stdafx.h c 後面使用的類要先宣告?負責儲存gamerole物件的內部狀態,並可防止gamerole以外的其他物件訪問備忘錄memento。備忘錄有兩個介面,caretaker只能看見備忘錄的窄藉口,他只能將備忘錄傳遞給其他物件。originator能夠看到乙個寬介面,允許他...