設計模式——備忘錄模式

在閻宏博士的《JAVA與模式》一書中開頭是這樣描述備忘錄(Memento)模式的:備忘錄模式又叫做快照模式(Snapshot Pattern)或Token模式,是對象的行為模式。備忘錄對象是一個用來存儲另外一個對象內部狀態的快照的對象。備忘錄模式的用意是在不破壞封裝的條件下,將一個對象的狀態捕捉(Capture)住,並外部化,存儲起來,從而可以在將來合適的時候把這個對象還原到存儲起來的狀態。備忘錄模式常常與命令模式和迭代子模式一同使用。

設計模式——備忘錄模式

備忘錄模式主要意圖是在不破壞封裝性的前提下,捕獲一個對象的內部狀態,並在該對象之外保存這個狀態,以便在合適的時機將該對象恢復到原先保存的狀態。結合起來理解,有三層含義:

  1. 不破壞封裝性:對象只釋放該暴露的接口,不能暴露不該對外釋放的接口;

  2. 捕獲對象內部狀態並外部化:保存對象的狀態,並外部化存儲起來,以便進行恢復;

  3. 對象內部狀態通過備忘錄對象存儲,保存在外部管理者類中。

設計模式——備忘錄模式

備忘錄模式的核心角色有:備忘錄角色(Memento)、發起人角色(Originator)、負責人角色(Caretaker)。

備忘錄角色

備忘錄角色用來存儲發起人對象的內部狀態,但是具體存儲哪些字段值有發起人角色決定。備忘錄對象的內部數據只能有發起人對象來訪問,其它對象不應該訪問到備忘錄對象的內部數據。概括起來,備忘錄角色的責任如下:

  1. 將發起人角色的內部狀態進行存儲,並進行外部化存儲;

  2. 備忘錄可以保護其內容不被髮起人(Originator)對象之外的任何對象所讀取,所以通常會把備忘錄對象作為發起人對象的內部類來實現,而且實現成私有的,然後通常一個窄接口來標識對象的類型,以便以外部交互。

發起人角色

發起人角色也稱之為原發器。發起人角色通過備忘錄對象來存儲某個時刻自身的狀態,同時也可以使用備忘錄保存的狀態進行恢復。發起人角色用途有兩個:

  1. 提供捕獲某個時刻的方法,在方法中創建備忘錄對象,把需要保存的狀態進行保存,然後把備忘錄對象外拋管理;

  2. 提供通過備忘錄對象進行狀態恢復的方法;

負責人角色

主要負責備忘錄對象的管理。這裡我們需要明確以下幾點:

  1. 備忘錄模式中並不一定需要一個負責人對象。廣義來說,調用發起人角色獲得備忘錄對象後,備忘錄放在哪裡,那個對象就是管理者對象。

  2. 負責人對象並不是只管理一個備忘錄對象,它可以管理多個備忘錄對象。

  3. 狹義的負責人只管理同一類的備忘錄對象,但廣義的管理者可以管理不同類型的備忘錄對象。

  4. 負責人對象需要實現的基本功能是:存入備忘錄對象和從中獲取備忘錄對象。從功能上看,就是一個緩存功能或一個簡單的對象實例池。

  5. 負責人角色雖然能存取備忘錄對象,但是不能訪問備忘錄對象的內部數據。

通俗點說,備忘錄就是一個普通類用來保存發起人角色的相關狀態,然後將該狀態交給負責人角色進行管理,這裡的管理具有保存和恢復功能。

案例演示

這裡就從魔獸世界的例子來說。剛學習翫魔獸世界的時候,先學習人機對戰,玩到正起興,室友突然喊你去吃飯,那隻能先保存下進度,關電腦降降溫,吃過飯回來直接打開剛才保存的進度,讀取完成後接著玩。在這個案例中,就是一個備忘錄模式的案例。

創建發起人角色/原發器角色

設計模式——備忘錄模式

在原發器的定義中,定義了一個獲取內部狀態的方法,並將內部狀態保存到備忘錄對象中。同時定義了一個loadGame方法用來讀取備忘錄中的內容。

定義備忘錄

設計模式——備忘錄模式

可以看到,備忘錄就是一個簡單的實體類,這個實體類用來存放原發器的狀態。這個類的內容只能被原發器訪問,即原發器與備忘錄對象之間建立的是一個寬接口。原發器能夠看到一個寬接口,允許它訪問所需的所有數據,來返回先前的狀態。通常實現成為原發器內的一個私有內部類。

定義負責人角色/管理者角色

設計模式——備忘錄模式

負責人角色用來管理備忘錄對象,管理者對象並不是只管理一個備忘錄對象,它可以管理多個備忘錄對象。管理者只能看到備忘錄的窄接口,這個接口的實現通常沒有任何的方法,只是一個類型標識。窄接口使得管理者只能將備忘錄傳遞給其他對象

客戶端

設計模式——備忘錄模式

運行結果

設計模式——備忘錄模式

備忘錄模式的優缺點

優點

  1. 更好的封裝性,通過使用備忘錄對象來封裝原發器對象的內部狀態,雖然這個對象保存在原發器對象的外部,但是由於備忘錄對象的窄接口並不提供任何方法,因為有效地保證了原發器內部狀態的封裝,不把原發器對象的內部實現細節暴露給外部。

  2. 簡化了原發器,備忘錄對象被保存在原發器對象之外,讓客戶來管理他們請求的狀態,從而讓原發器對象得到簡化。

缺點

頻繁地創建備忘錄對象,可能導致較大的開銷

相關模式

(1)備忘錄模式和命令模式

命令模式實現中,在實現命令的撤銷和重做的時候,可以使用備忘錄模式,在命令操作的時候記錄下操作前後的狀態,然後在命令撤銷和重做的時候,直接使用相應的備忘錄對象來恢復狀態就可以了。

(2)備忘錄模式和原型模式

創建備忘錄對象時,如果原發器對象中全部或大部分的狀態都需要保存,一個簡潔的方式就是直接克隆一個原發器對象。也就是說,這個時候備忘錄對象裡面存放的是一個原發器對象的實例。

設計模式——備忘錄模式


分享到:


相關文章: