備忘錄模式包含以下幾個角色: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()); } }