20、行爲型-備忘錄模式(Memento)

備忘錄模式(Memento Pattern):在不破壞封裝的前提下,捕獲一個對象的內部狀態,並在該對象以外保存這個狀態,這樣能夠在之後將對象恢復到原先保存的狀態。它是一種對象行爲型模式,其別名爲Token。

備忘錄模式包含以下幾個角色:java

●Originator(原發器):它是一個普通類,能夠建立一個備忘錄,並存儲它的當前內部狀態,也可使用備忘錄來恢復其內部狀態,通常將須要保存內部狀態的類設計爲原發器。
●Memento(備忘錄):存儲原發器的內部狀態,根據原發器來決定保存哪些內部狀態。備忘錄的設計通常能夠參考原發器的設計,根據實際須要肯定備忘錄類中的屬性。須要注意的是,除了原發器自己與負責人類以外,備忘錄對象不能直接供其餘類使用,原發器的設計在不一樣的編程語言中實現機制會有所不一樣。
●Caretaker(負責人):負責人又稱爲管理者,它負責保存備忘錄,可是不能對備忘錄的內容進行操做或檢查。在負責人類中能夠存儲一個或多個備忘錄對象,它只負責存儲對象,而不能修改對象,也無須知道對象的實現細節。

一、主要優勢編程

(1)它提供了一種狀態恢復的實現機制,使得用戶能夠方便地回到一個特定的歷史步驟,當新的狀態無效或者存在問題時,可使用暫時存儲起來的備忘錄將狀態復原。
(2)備忘錄實現了對信息的封裝,一個備忘錄對象是一種原發器對象狀態的表示,不會被其餘代碼所改動。備忘錄保存了原發器的狀態,採用列表、堆棧等集合來存儲備忘錄對象能夠實現屢次撤銷操做。

二、主要缺點編程語言

資源消耗過大,若是須要保存的原發器類的成員變量太多,就不可避免須要佔用大量的存儲空間,每保存一次對象的狀態都須要消耗必定的系統資源。

三、適用場景測試

(1)保存一個對象在某一個時刻的所有狀態或部分狀態,這樣之後須要時它可以恢復到先前的狀態,實現撤銷操做。
(2)防止外界對象破壞一個對象歷史狀態的封裝性,避免將對象歷史狀態的實現細節暴露給外界對象。

英雄聯盟中的備忘錄模式(時空裂痕):this

輸入圖片說明

/**
 * 2018/12/6
 * StateOriginator
 *
 * @author machuanpeng
 */
public class StateOriginator {

    private String time;
    
    private String event;
 
    public StateOriginator(){}
 
  // 建立一個備忘錄對象
    public Memento createMemento() {
    return new Memento(this);
    }
 
  // 根據備忘錄對象恢復原發器狀態
    public void restoreMemento(Memento memento) {
     this.time = memento.getTime();
        this.event = memento.getEvent();
    }
}
/**
 * 2018/12/6
 * Memento
 *
 * @author machuanpeng
 */
public class Memento {  
  
    private String time;
    
    private String event;
      
    public Memento(StateOriginator originator) {  
     this.time = originator.getTime();
        this.event = originator.getEvent(); 
    }  
}
/**
 * 2018/12/6
 * Caretaker
 *
 * @author machuanpeng
 */

public class Caretaker {
    
	private Memento memento;
 
	public Memento getMemento() {
		return this.memento;
	}
 
	public void setMemento(Memento memento) {
		this.memento=memento;
	}
}

測試:設計

public class Client {
	public static void main(String args[]) {
        // 建立原始類  
        StateOriginator originator = new StateOriginator();  
  		originator.setTime("2018-12-10 17:07:00");
        originator.setEvent("藍方在打大龍");
        // 建立備忘錄  
        Memento memento = originator.createMemento();  
        Caretaker caretaker = new Caretaker();
        caretaker.setMemento(memento);
        System.out.println("初始化狀態爲:"+originator.getTime()+originator.getEvent()); 
        // 修改原始類的狀態  
        originator.setTime("2018-12-10 17:10:00");
        originator.setEvent("紅方在打小龍");
        System.out.println("修改後的狀態:"+originator.getTime()+originator.getEvent()); 
        // 回覆原始類的狀態  
        originator.restoreMemento(caretaker.getMemento());  
        System.out.println("恢復後的狀態:"+originator.getTime()+originator.getEvent());
	}
}
相關文章
相關標籤/搜索