抽絲剝繭——備忘錄設計模式

MakerStack 發表於 2020-10-30

備忘錄設計模式

兄弟們好,今天來和大家聊聊備忘錄設計模式。

它的主要思想是:儲存一個物件在某一時刻的副本,並且該物件的副本在外部不可以被訪問,同時該物件的副本可以被內部重新載入和修改

看到這裡,有沒有想到我們的序列化。在學習IO流的時候我們可以通過Serializable實現物件的序列化,這個序列化的過程就是一個備忘錄的過程,通過對當前物件序列化,包含當前的狀態,當需要的時候再將這個狀態載入進來。

我們常常見過的遊戲存檔就是這個實現原理,將所有涉及到物件全部序列化,包含再本地檔案中,然後讀檔的時候再載入進去。

我們來看一下它類圖實現:

抽絲剝繭——備忘錄設計模式

它主要有三個角色:

  • Originator用來描述一個需要被進行備忘錄的物件,它可以主動的建立一個備忘錄,並且設定其狀態
  • Memento備忘錄物件,用來儲存Originator物件的狀態,提供兩個介面用於讀取和設定物件的狀態
  • Caretake。執行具體的備忘錄呼叫。對於它而言備忘錄僅僅可以檢視,但不能修改

我們來看一下具體的程式碼實現:

備忘錄介面,一個標識

interface Memento{

}

需要記錄的物件,寬介面,可以訪問備忘錄的所有資訊

class Originator{
    private String state ;

    public Memento createMemento(){
        return new InnerMemento(state);
    }

    public void restoreState(Memento memento){
        this.state = ((InnerMemento)memento).getState();
    }

    public void setState(String state) {
        this.state = state;
    }

    class InnerMemento implements Memento{
        private String state ;

        public InnerMemento(String state){
            this.state = state ;
        }

        public void setState(String state) {
            this.state = state;
        }

        public String getState() {
            return state;
        }
    }
}

具體負責呼叫,窄介面,僅僅可以檢視備忘錄

class Caretaker{
    private Originator originator ;
    public Caretaker(Originator originator){
        this.originator = originator ;
    }
    public Memento createMemento(){
        return originator.createMemento();
    }
    public void restoreState(Memento memento){
        originator.restoreState(memento);
    }
}

具體呼叫

public static void main(String[] args) {
        Originator originator = new Originator();
        Caretaker caretaker = new Caretaker(originator);
        //儲存當前狀態
        Memento memento = caretaker.createMemento();

        originator.setState("我的");
        caretaker.createMemento();
    }

有沒有發現,這個設計模式強調了一個安全訪問的原則,通過對不同的介面實現了一個寬介面和窄介面,來實現不同層次的呼叫。這個模式常常會和命令設計模式聯合起來,用來記錄undo操作,例如mysql持久化。

好啦,今天的設計模式就到這裡了,兄弟們,晚安。