設計模式-備忘錄模式

###模式定義:數據庫

在不破環封裝行性的前提下,捕獲一個對象的內部狀態,並在該對象以外保存這個狀態。這樣就能夠將該對象恢復到原先保存的狀態。 ###模式場景緩存

  1. 錄入大批人員資料的時候。正在錄入當前人資料時,發現上一我的錄錯了,此時須要恢復到上一我的的資料,進行修改。this

  2. Word編輯時,突然斷電或電腦死機,再打開時,能夠看到Word提示你恢復到之前的文檔。code

###模式結構 模式結構對象

  1. Memento:備忘錄。主要用來存儲原發器對象的內部狀態,可是具體須要存儲哪些數據是由原發器對象來決定的。另外備忘錄應該只能由原發器對象來訪問它內部的數據,原發器外部的對象不該該能訪問到備忘錄對象的內部數據。接口

  2. Originator:原發器。使用備忘錄來保存某個時刻原發器自身的狀態,也可使用備忘錄來恢復內部狀態。遊戲

  3. Caretaker:備忘錄管理者,或者稱爲備忘錄負責人。主要負責保存備忘錄對象,可是不能對備忘錄對象的內容進行操做或檢查。事務

###代碼實現 ####UML圖 ####源碼開發

public interface FlowAMockMemento {
}

public class FlowAMock {
    private String flowName;
    private int tempResult;
    private String tempState;

    public FlowAMock(String flowName) {
        this.flowName = flowName;
    }

    public void runPhaseOne(){
        tempResult = 3;
        tempState = "phaseOne";
    }
    public void schema1(){
        this.tempState += ",Schema1";
        System.out.println(this.tempState+":now run " + tempResult);
        this.tempResult += 11;
    }

    public void schema2(){
        this.tempState += ",Schema2";
        System.out.println(this.tempState+":now run " + tempResult);
        this.tempResult += 22;
    }

    public FlowAMockMemento createMemento(){
        return new MementoImpl(this.tempResult,this.tempState);
    }

    public void setMemento(FlowAMockMemento memento){
        MementoImpl mementoImpl = (MementoImpl) memento;
        this.tempResult = mementoImpl.getTempResult();
        this.tempState = mementoImpl.getTempState();
    }

    /**
     * 真正的備忘錄對象,實現備忘錄窄接口
     * 實現成爲私有內部類
     */
    private static class MementoImpl implements FlowAMockMemento{
        @Getter
        private int tempResult;
        @Getter
        private String tempState;

        public MementoImpl(int tempResult, String tempState) {
            this.tempResult = tempResult;
            this.tempState = tempState;
        }
    }
}

@Data
public class FlowAMementoCareTaker{

    private FlowAMockMemento memento;
}

public class Client {
    public static void main(String[] args) {
        FlowAMock mock = new FlowAMock("testFlow");
        mock.runPhaseOne();

        FlowAMementoCareTaker careTaker = new FlowAMementoCareTaker();
        FlowAMockMemento memento = mock.createMemento();
        careTaker.setMemento(memento);

        mock.schema1();
        mock.setMemento(memento);
        mock.schema2();
    }
}

###模式的優缺點 ####模式的優勢文檔

  1. 更好的封裝性

    備忘錄模式經過使用備忘錄對象,來封裝原發器對象的內部狀態,雖然這個對象是保存在原發器對象的外部,可是因爲備忘錄對象的窄接口並不提供任何方法,這樣有效的保證了對原發器對象內部狀態的封裝,不把原發器對象的內部實現細節暴露給外部。

  2. 簡化了原發器

    備忘錄模式中,備忘錄對象被保存到原發器對象以外,讓客戶來管理他們請求的狀態,從而讓原發器對象獲得簡化。

  3. 窄接口和寬接口

####模式的缺點

  1. 可能會致使高開銷

    備忘錄模式基本的功能,就是對備忘錄對象的存儲和恢復,它的基本實現方式就是緩存備忘錄對象。這樣一來,若是須要緩存的數據量很大,或者是特別頻繁的建立備忘錄對象,開銷是很大的。

###思考

模式本質:保存和恢復內部狀態

###開發中的應用場景:

  1. 棋類遊戲,悔棋

  2. 普通軟件,撤銷操做

  3. 數據庫軟件中的,事務管理的,回滾操做

  4. Photoshop軟件

###相關模式

  1. 備忘錄模式和命令模式 這兩個模式能夠組合使用。

命令模式實現中,在實現命令的撤銷和重作的時候,可使用備忘錄模式,在命令操做的時候記錄下操做先後的狀態,而後在命令撤銷和重作的時候,直接使用相應的備忘錄對象來恢復狀態就能夠了。 在這種撤銷的執行順序和重作執行順序可控的狀況下,備忘錄對象還能夠採用增量式記錄的方式,能夠減小緩存的數據量。

  1. 備忘錄模式和原型模式 這兩個模式能夠組合使用。

在原發器對象建立備忘錄對象的時候,若是原發器對象中所有或者大部分的狀態都須要保存,一個簡潔的方式就是直接克隆一個原發器對象。也就是說,這個時候備忘錄對象裏面存放的是一個原發器對象的實例。

相關文章
相關標籤/搜索