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