生活随笔
收集整理的這篇文章主要介紹了
《研磨设计模式》chap19 备忘录模式
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
應用場景:需要保存對象的狀態和值。
1. 簡介
public interface Memento {
}public class Originator {//表示原發器的狀態 private String state =
"";public Memento createMemento() {//創建保存原發器對象的狀態的備忘錄對象 return new
MementoImpl(state
);}//重新設置原發器對象的狀態,讓其回到備忘錄對象記錄的狀態 public void setMemento(Memento memento) {MementoImpl mementoImpl =
(MementoImpl
)memento
;this.state = mementoImpl.
getState();}//真正的備忘錄對象,實現備忘錄窄接口 private static class MementoImpl implements Memento{ private String state =
"";public MementoImpl(String state){this.state = state
;}public String getState() {return state
;}}
}public class Caretaker{ private Memento memento = null
; public void saveMemento(Memento memento){this.memento = memento
;} public Memento retriveMemento(){return this.memento
;}
}
2. 應用到場景
2.1. 創建備忘錄
2.2. 從備忘錄恢復
public interface FlowAMockMemento extends Serializable{
}public class FlowAMementoCareTaker {//記錄被保存的備忘錄對象 private FlowAMockMemento memento = null
;//保存備忘錄對象 public void saveMemento(FlowAMockMemento memento){this.memento = memento
;}// 獲取被保存的備忘錄對象 public FlowAMockMemento retriveMemento(){return this.memento
;}
}public class FlowAMementoFileCareTaker { //保存備忘錄對象 public void saveMemento(FlowAMockMemento memento){//寫到文件中ObjectOutputStream out = null
;try{out = new
ObjectOutputStream(new
BufferedOutputStream(new
FileOutputStream("FlowAMemento")));out.
writeObject(memento
);...
}//獲取被保存的備忘錄對象 public FlowAMockMemento retriveMemento(){FlowAMockMemento memento = null
;//從文件中獲取備忘錄數據ObjectInputStream in = null
;try{in = new
ObjectInputStream(new
BufferedInputStream(new
FileInputStream("FlowAMemento")));memento =
(FlowAMockMemento
)in.
readObject();...return memento
;}
}public class FlowAMock implements Serializable {//流程名稱,不需要外部存儲的狀態數據 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(){ } //創建保存原發器對象的狀態的備忘錄對象 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{ private int tempResult
;//示意,保存某個中間結果 private String tempState
;//示意,保存某個中間結果public MementoImpl(int tempResult,String tempState){this.tempResult = tempResult
;this.tempState = tempState
;}public int getTempResult() {return tempResult
;}public String getTempState() {return tempState
;}}
}public class FlowAMockPrototype implements Cloneable { private String flowName
; private int tempResult
;//示意,代指某個中間結果,需要外部存儲的狀態數據 private String tempState
;public FlowAMockPrototype(String flowName){this.flowName = flowName
;}//示意,運行流程的第一個階段 public void runPhaseOne(){//在這個階段,可能產生了中間結果,示意一下tempResult = 3
;tempState =
"PhaseOne";}//示意,按照方案一來運行流程后半部分 public void schema1(){//示意,需要使用第一個階段產生的數據
} public void schema2(){ } //創建保存原發器對象的狀態的備忘錄對象 public FlowAMockMemento createMemento() { return new
MementoImplPrototype((FlowAMockPrototype
) this.
clone()); } //重新設置原發器對象的狀態,讓其回到備忘錄對象記錄的狀態 public void setMemento(FlowAMockMemento memento) {MementoImplPrototype mementoImpl =
(MementoImplPrototype
)memento
;this.tempResult = mementoImpl.
getFlowAMock().tempResult
;this.tempState = mementoImpl.
getFlowAMock().tempState
;}//真正的備忘錄對象,實現備忘錄窄接口,// 實現成私有的內部類,不讓外部訪問 private static class MementoImplPrototype implements FlowAMockMemento{private FlowAMockPrototype flowAMock = null
; public MementoImplPrototype(FlowAMockPrototype f){this.flowAMock = f
;} public FlowAMockPrototype getFlowAMock() {return flowAMock
;}}
}public static void main(String[] args) {// 創建模擬運行流程的對象FlowAMock mock = new
FlowAMock("TestFlow");//運行流程的第一個階段mock.
runPhaseOne();//創建一個管理者FlowAMementoCareTaker careTaker = new
FlowAMementoCareTaker();//創建此時對象的備忘錄對象,并保存到管理者對象那里,后面要用FlowAMockMemento memento = mock.
createMemento();careTaker.
saveMemento(memento
);//按照方案一來運行流程后半部分mock.
schema1();//從管理者獲取備忘錄對象,然后設置回去,//讓模擬運行流程的對象自己恢復自己的內部狀態mock.
setMemento(careTaker.
retriveMemento());//按照方案二來運行流程后半部分mock.
schema2();}
3. redo/undo借助備忘錄模式
// todo
4. 總結
備忘錄模式的本質:保存和恢復內部狀態
-
如果必須保存一個對象在某一個時刻的全部或者部分狀態,方便在以后需要的時候把該對象恢復到先前的狀態,可以使用備忘錄模式。
-
使用備忘錄對象來封裝和保存需要保存的內部狀態,然后把備忘錄對象保存到管理者對象中,在需要的時候,再從管理者對象中獲取備忘錄對象,來恢復對象的狀態。
-
如果需要保存一個對象的內部狀態,但是如果用接口來讓其他對象直接得到這些需要保存的狀態,將會暴露對象的實現細節并破壞對象的封裝性,這時可以使用備忘錄模式,把備忘錄對象實現成為原發器對象的內部類,而且還是私有的,從而保證只有原發器對象才能訪問該備忘錄對象。這樣既保存了需要保存的狀態,又不會暴露原發器對象的內部實現細節。
總結
以上是生活随笔為你收集整理的《研磨设计模式》chap19 备忘录模式的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。