一、“Mementor”模式和“堆棧”的結合-“GUI界面撤銷功能”的實現
·當用戶在面板中拖動一個組件到編輯區時,應用程序為編輯區創建一個備忘錄,并把它加入到一個堆棧中(注意此時備忘錄中包含的是操作前的狀態,而非操作后的狀態)
·當用戶單擊“撤銷”按鈕時,應用程序就將堆棧頂部的備忘錄彈出,然后將編輯區恢復為該備忘錄所記錄的狀態
當可視化應用程序啟動后,首先向空的堆棧中壓入一個初始的空備忘錄,并且保證絕對不會將該備忘錄從棧中彈出,從而確保該棧的頂部總是有一個有效的備忘錄。當棧中僅包含一個備忘錄的時候,應用程序應當禁用“撤銷”按鈕
二、“Mementor”模式和“Observer”模式的結合-“通知式恢復”
在某些情況下,我們希望為GUI組件注冊一些監聽器,當組件的狀態發生改變時,可以通知所有對它感興趣的監聽器,這種情況我們可以用“Observer”模式來實現。
還是以我們上面的例子來說:假如用戶從面板中拖動一個組件到編輯區后,有幾個監聽器對它感興趣,并且采取了相應的操作,現在用戶單擊了“撤銷”按鈕,那么我們應該把這個事件通知所有監聽器,告訴他們必須恢復之前所有的狀態。這種情況就可以把兩種模式結合起來使用:
·當對象被創建時,激活并為該對象注冊監聽器(觀察著),監聽器創建一個初始化備忘錄,保存編輯區的原始信息
·當對象(被觀察著)被銷毀(用戶單擊“撤銷”按鈕時),向所有注冊的監聽器發送信息
·監聽器(觀察者)接收到信息,從備忘錄中取出編輯區信息的備忘錄,恢復當前編輯區的狀態
三、“Mementor”模式和“Observer”模式、“責任鏈”模式的結合-“鏈式通知恢復”
在上面我們提到了將“Mementor”模式和“Observer”模式結合起來達到到“通知式恢復”的效果,考慮下面一個情況:
如果我們在安裝一個軟件或執行一個長時間、多次交互的情況,加入用戶在最后一個操作中選擇了“取消”操作,我們應該怎么做呢?
我的想法是在為每一次操作創建一個備忘錄,并將其放在“責任鏈”上,當最后用戶選擇取消時,沿著這條“責任鏈”一個個通知觀察者,由觀察者取出備忘錄,執行恢復工作。
注意:這個方法和第二個方法有點區別:第二個方法不管恢復的順序,而第三種方法適合講究恢復順序的情況,例如前面提到的軟件安裝的撤銷。
四、“Mementor”模式和“Flyweight”模式的結合:減少相同對象的拷貝
用于保存對象狀態的“備忘錄”對象,必須擁有一份和被保存對象相同的屬性拷貝。
對于“備忘錄”有可能導致內存消耗過大的情況,如果對象中的屬性是“公用的”(即多個對象可以共享一個屬性),那么我們可以考慮采用“享元模式”,減少相同屬性對象的創建。但是這個方法對于屬性多為運行時確定的情況作用不大。
-------------------------------------------------------------
生活就像打牌,不是要抓一手好牌,而是要盡力打好一手爛牌。