小A:“備忘錄模式要怎麼去實現?”
大B:“我詳細給你說。”
1、備忘錄模式中的角色
發起人:創建含有內部狀態的備忘錄對象,並使用備忘錄對象存儲狀態。
負責人:負責人保存備忘錄對象,但不檢查備忘錄對象的內容。
備忘錄:備忘錄對象將發起人對象的內部狀態存起來,並保證其內容不被髮起人對象之外的對象像讀齲
注意:在備忘錄的角色中,定義了他必須對不同的人提供不同的接口,對發起人提供寬接口,對其它任何人提供窄。
接口:也許你說我都提供寬接口了。這也是備忘錄的一種實現,叫做白箱備忘錄,不過這種方法的封裝沒有設計。好,安全性不夠好。
2、白箱備忘錄的實現:
publicclassOriginator{
privateStringstate;
publicMementoCreateMemento(){
returnnewMemento(state);
}
publicvoidrestoreMemento(Mementomemento){
this.state=memento.getState();
}
publicStringgetState(){
returnthis.state;
}
publicvoidsetState(Stringstate){
this.state=state;
System.out.println(“Currentstate=”+this.state);
}
}
publicclassMemento{
privateStringstate;
publicMemento(Stringstate){
this.state=state;
}
publicStringgetState(){
returnthis.state;
}
publicvoidsetState(){
this.state=state;
}
}
publicclassCaretaker{
privateMementomemento;
publicMementoretrieveMemento(){
returnthis.memento;
}
publicvoidsaveMemento(Mementomemento){
this.memento=memento;
}
}
publicclassClient{
privatestaticOriginatoro=newOriginator();
privatestaticCaretakerc=newCaretaker();
publicstaticvoidmain(Sting[]args){
o.setState(“ON”);
c.saveMemento(o.createMemento());
o.setState(“OFF”);
o.restoreMemento(c.retrieveMemento());
}
}
白箱的優點:實現簡單。
白箱的缺點:上邊說了,破壞了封裝,安全性有些問題。
說明:這裡白箱的實現只保存了一個狀態,其實是可以保存多個狀態的。
3、雙接口的實現,寬窄接口(黑箱)
如何實現寬窄接口呢?內部類也許是個好方法。我們把備忘錄類設計“成發起人”的內部類,但這樣還有的問題是同一package中的其它類也能訪問到,爲了解決這個問題,我們可以把“備忘錄”的方法設計成私有的方法,這樣就可以保證封裝,又保證發起人能訪問到。實現如下:
定義窄接口。
publicinterfaceNarrowMemento{
publicvoidnarrowMethod();
}
classOriginator{
private
Stringstate;
privateNarrowMementomemento;
publicOriginator(){
}
publicNarrowMementocreateMemento(){
memento=newMemento(this.state);
returnmemento;
}
publicvoidrestoreMemento(NarrowMementomemento){
MementoaMemento=(Memento)memento;
this.setState(aMemento.getState());
}
publicStringgetState(){
returnthis.state;
}
publicvoidsetState(Stringstate){
this.state=state;
}
//內部類
protectedclassMementoimplementsNarrowMemento{
privateStringsavedState;
privateMemento(StringsomeState){
saveState=someState;
}
privatevoidsetState(StringsomeState){
saveState=someState;
}
privateStringgetState()
{
returnsaveState;
}
publicvoidnarrowMethod(){
System.out.println(“thisisnarrowmethod”);
}
}
publicNarrowMementogetNarrowMemento(){
returnmemento;
}
}
publicclassCaretaker{
privateNarrowMementomemento;
publicNarrowMementoretrieveMemento(){
returnthis.memento;
}
publicvoidsaveMemento(NarrowMementomemento){
this.memento=memento;
}
}
publicclassClient{
privatestaticOriginatoro=newOriginator();
privatestaticCaretakerc=newCaretaker();
publicstaticvoidmain(String[]args){
//usewideinterface
o.setState(“On”);
c.saveMemento(o.createMemento());
o.setState(“Off”);
o.restoreMemento(c.retrieveMemento());
//usenarrowinterface
NarrowMementomemento=o.getNarrowMemento();
memento.narrowMethod();
}
}
大B:“還要注意的是:1、前邊兩個例子都是記錄了單個狀態(單check點),要實現多個狀態點很容易,只須要把記錄state的字符串換成一個list,然後添加,取得。如果須要隨機須得狀態點,也可以用map來存放。這樣多個check點就實現了。2、一般情況下可以擴展負責人的功能,讓負責人的功能更強大,從而讓客戶端的操做更少些。解放客戶端。3、自述歷史模式,這個就是把發起人,負責人寫在一個類中,平時的應用中這種方法比較常見。”