一、 模式定義:
          在不破壞封裝的前提下,捕獲一個對象的內部狀態,并在該對象之外保存這個狀態。這樣就可以將該對象恢復到原先保存前的狀態。
          二、 模式解說
          在程序運行過程中,某些對象的狀態處在轉換過程中,可能由于某種原因需要保存此時對象的狀態,以便程序運行到某個特定階段,需要恢復到對象之前處于某個點時的狀態。如果使用一些公有接口讓其它對象來得到對象的狀態,便會暴露對象的實現細節。
          三、 結構圖
           
          1) 備忘錄(Memento)角色:備忘錄角色存儲“備忘發起角色”的內部狀態。“備忘發起角色”根據需要決定備忘錄角色存儲“備忘發起角色”的哪些內部狀態。為了防止“備忘發起角色”以外的其他對象訪問備忘錄。備忘錄實際上有兩個接口,“備忘錄管理者角色”只能看到備忘錄提供的窄接口——對于備忘錄角色中存放的屬性是不可見的。“備忘發起角色”則能夠看到一個寬接口——能夠得到自己放入備忘錄角色中屬性。
          2) 備忘發起(Originator)角色:“備忘發起角色”創建一個備忘錄,用以記錄當前時刻它的內部狀態。在需要時使用備忘錄恢復內部狀態。
          3) 備忘錄管理者(Caretaker)角色:負責保存好備忘錄。不能對備忘錄的內容進行操作或檢查。
          四、一個例子
          這個例子是我從網上找到的,我覺得它比較形象,就拿過來直接用了。下面是這個例子的代碼:
           class WindowsSystem{
           private String state;
           public Memento createMemento(){ //創建系統備份
            return new Memento(state);
           }
           public void restoreMemento(Memento m){ //恢復系統
            this.state=m.getState();
           }
           public String getState() {
            return state;
           }
           public void setState(String state) {
            this.state = state;
            System.out.println("當前系統處于"+this.state);
           }
           
          }
          class Memento{
           private String state;
           
           public Memento(String state) {
            this.state = state;
           }
           public String getState() {
            return state;
           }
           public void setState(String state) {
            this.state = state;
           }
          }
          class User{
           private Memento memento;
           public Memento retrieveMemento() {  //恢復系統
               return this.memento;
           }
           public void saveMemento(Memento memento){  //保存系統
               this.memento=memento;
           }
          }

          public class Test{

           public static void main(String[] args) {
           
             WindowsSystem Winxp = new WindowsSystem(); //Winxp系統
             User user = new User();   //某一用戶
             Winxp.setState("好的狀態");   //Winxp處于好的運行狀態
             user.saveMemento(Winxp.createMemento()); //用戶對系統進行備份,Winxp系統要產生備份文件
             Winxp.setState("壞的狀態");   //Winxp處于不好的運行狀態
             Winxp.restoreMemento(user.retrieveMemento());   //用戶發恢復命令,系統進行恢復
             System.out.println("當前系統處于"+Winxp.getState());
            }

          }
          在本例中,WindowsSystem是發起人角色(Orignation),Memento是備忘錄角色(Memento),User是備忘錄管理角色(Caretaker)。Memento提供了兩個接口(注意這里的接口,并不是java中的接口,它指的是可被外界調用的方法):一個是為WindowsSystem 類的寬接口,能夠得到WindowsSystem放入Memento的state屬性,代碼見WindowsSystem的createMemento方法和restoreMemento方法,createMemento方法向Memento放入state屬性,restoreMemento方法獲得放入的state屬性。另一個是為User類提供的窄接口,只能管理Memento而不能對它的內容進行任何操作(見User類)。
          五、 優缺點
          1) 保持封裝邊界 使用備忘錄可以避免暴露一些只應由原發器管理卻又必須存儲在原發器之外的信息。該模式把可能很復雜的Originator內部信息對其他對象屏蔽起來,從而保持了封裝邊界。
          2) 它簡化了原發器 在其他的保持封裝性的設計中,Originator負責保持客戶請求過的內部狀態版本。這就把所有存儲管理的重任交給了Originator。讓客戶管理它們請求的狀態將會簡化Originator,并且使得客戶工作結束時無需通知原發器。
          3) 使用備忘錄可能代價很高 如果原發器在生成備忘錄時必須拷貝并存儲大量的信息,或者客戶非常頻繁地創建備忘錄和恢復原發器狀態,可能會導致非常大的開銷。除非封裝和恢復Originator狀態的開銷不大,否則該模式可能并不合適。
          4) 維護備忘錄的潛在代價 管理器負責刪除它所維護的備忘錄。然而,管理器不知道備忘錄中有多少個狀態。因此當存儲備忘錄時,一個本來很小的管理器,可能會產生大量的存儲開銷。
          六、 適用性
          1)必須保存一個對象在某一個時刻的(部分)狀態,這樣以后需要時它才能恢復到先前的狀態。
          2)如果一個用接口來讓其它對象直接得到這些狀態,將會暴露對象的實現細節并破壞對象的封裝性。
          七、參考
           http://tech.it168.com/n/d/2007-05-20/200705201437328.shtml
          http://www.cnblogs.com/John-zhaohui/archive/2007/08/20/862663.html
          http://www.cppblog.com/converse/archive/2006/08/09/11063.html
          http://java.ccidnet.com/art/3741/20030715/544777_1.html
          http://blog.csdn.net/qutr/archive/2006/08/01/1007600.aspx

          posts - 146, comments - 143, trackbacks - 0, articles - 0

          Copyright © flustar

          主站蜘蛛池模板: 黄石市| 兖州市| 苍溪县| 临湘市| 乌鲁木齐县| 金乡县| 苍南县| 浏阳市| 吉首市| 莱州市| 安徽省| 星座| 琼结县| 宜阳县| 斗六市| 神农架林区| 肇东市| 攀枝花市| 盐城市| 来凤县| 鸡西市| 宁强县| 容城县| 盘锦市| 麻阳| 太仆寺旗| 伊川县| 兴宁市| 邵阳县| 雅江县| 岳池县| 祁连县| 伊宁县| 麻栗坡县| 兰州市| 株洲市| 安庆市| 西青区| 桂林市| 松溪县| 和硕县|