備忘錄模式java
概述:在不破壞封裝性的前提下,捕獲一個對象的內部狀態,並在該對象以外保存這個狀態.這樣能夠將對象恢復到原先保存的狀態.測試
幫助理解:備忘錄模式就是爲對象提供一個備份的地方,當對象想要回滾到前一個狀態時,調用備忘錄對象直接就能夠恢復.this
備忘錄模式說包含的角色spa
Originator : 原發器,也就是發起者.記錄有當前時刻自身的內部狀態,負責建立一個備忘錄Memento,用於記錄當前時刻自身的內部狀態,並可以使用備忘錄恢復內部狀態.Originator能夠根據須要決定Memento存儲本身的哪些內部狀態(發起者可能有不少內部狀態,能夠決定哪些由備忘錄備份)code
Memento : 備忘錄.負責存儲Originator對象的內部狀態,並能夠防止Originator以外的其它對象訪問備忘錄.備忘錄有兩個接口.Caretaker只能看到備忘錄的窄接口,他只能將備忘錄對象傳遞給其它對象.Originator卻可以看到備忘錄的寬接口.容許它訪問返回到先前狀態所須要的全部數據.對象
Caretaker : 管理者.負責保存備忘錄.可是不能對備忘錄的內容進行操做和訪問.只可以將備忘錄傳遞給其它對象.接口
優勢資源
有時一些發起人對象的內部信息必須保存在發起人對象之外的地方,可是必須由發起人對象本身讀取.這時使用備忘錄模式能夠將複雜的發起人內部信息對其它對象屏蔽起來.從而能夠恰當的保持封裝的邊界.get
備忘錄模式簡化了發起者類.發起者再也不須要管理和保存其內部狀態的一個個版本.客戶端能夠自行管理他們所須要的這些狀態的版本.class
當發起者角色的狀態發生改變的時候.有可能這個狀態無效,須要回滾到前一個狀態.這時候可使用暫時存儲起來的備忘錄將狀態進行還原.
缺點
若是發起者角色的狀態有不少而且須要完整的儲存到備忘錄對象中.那麼備忘錄對象會很消耗資源.
注意事項
備忘錄模式最理想的狀況是隻容許生成該備忘錄的那個原發器可以訪問這個備忘錄的內部狀態.
/** * 〈備忘錄對象類〉 * * @author vegetate * @create 2018/11/12 17:08 */ public class MemoBean { private int useTime;//使用時間 private String deviceName;//設備名稱 private int stateLevel;//狀態 public int getUseTime() { return useTime; } public void setUseTime(int useTime) { this.useTime = useTime; } public String getDeviceName() { return deviceName; } public void setDeviceName(String deviceName) { this.deviceName = deviceName; } public int getStateLevel() { return stateLevel; } public void setStateLevel(int stateLevel) { this.stateLevel = stateLevel; } }
/** * 〈備忘錄管理對象〉 * * @author vegetate * @create 2018/11/12 17:11 */ public class MemoManager { MemoBean memento; public MemoBean getMemento() { return memento; } public void setMemento(MemoBean memento) { this.memento = memento; } }
/** * 〈發起者對象〉 * * @author vegetate * @create 2018/11/12 17:13 */ public class MemoRole { private int useTime;// 使用時間 private String deviceName;// 設備名稱 private int stateLevel;// 狀態 public MemoRole(String deviceName, int useTime, int stateLevel) { super(); this.useTime = useTime; this.deviceName = deviceName; this.stateLevel = stateLevel; } public MemoRole() { } public int getUseTime() { return useTime; } public void setUseTime(int useTime) { this.useTime = useTime; } public String getDeviceName() { return deviceName; } public void setDeviceName(String deviceName) { this.deviceName = deviceName; } public int getStateLevel() { return stateLevel; } public void setStateLevel(int stateLevel) { this.stateLevel = stateLevel; } public MemoBean createMemoObject() { MemoBean memento = new MemoBean(); memento.setDeviceName(deviceName); memento.setStateLevel(stateLevel); memento.setUseTime(useTime); return memento; } public void setMemento(MemoBean memento) { this.deviceName = memento.getDeviceName(); this.stateLevel = memento.getStateLevel(); this.useTime = memento.getUseTime(); } /** * 獲取對象當前狀態 */ public void getCurrentState() { System.out.println("當前設備名稱:" + this.deviceName + "當前使用時間:" + this.useTime + "當前工做狀態:" + this.stateLevel); } }
測試類
/** * 〈測試類〉 * * @author vegetate * @create 2018/11/12 17:14 */ public class Test { public static void main(String[] args) { // 新建備忘錄發起者對象 MemoRole role = new MemoRole("發電機", 0, 1); // 新建備忘錄管理者 MemoManager manager = new MemoManager(); // 角色初始狀態 System.out.println("機器開始發電:"); role.getCurrentState(); // 利用備忘錄模式保存當前狀態 System.out.println("---保存當前的機器狀態---"); manager.setMemento(role.createMemoObject()); role.setDeviceName("發電機"); role.setStateLevel(5); role.setUseTime(1000); System.out.println("已經持續發電1000小時"); role.getCurrentState(); // 恢復保存的角色狀態 role.setMemento(manager.getMemento()); System.out.println("恢復後發電機當前狀態:"); role.getCurrentState(); } }
結果: 機器開始發電: 當前設備名稱:發電機當前使用時間:0 當前工做狀態:1 —保存當前的機器狀態— 已經持續發電N小時 當前設備名稱:發電機當前使用時間:1000 當前工做狀態:5 恢復後發電機當前狀態: 當前設備名稱:發電機當前使用時間:0 當前工做狀態1