Movatterモバイル変換


[0]ホーム

URL:


Jump to content
WikibooksThe Free Textbook Project
Search

Memento

25% developed
From Wikibooks, open books for an open world
<Computer Science Design Patterns

MediatorComputer Science Design Patterns
Memento
Model–view–controller
Table of content

Briefly, the Originator (the object to be saved) creates a snap-shot of itself as a Memento object, and passes that reference to the Caretaker object. The Caretaker object keeps the Memento until such a time as the Originator may want to revert to a previous state as recorded in the Memento object.

Implementation in Java

The followingJava program illustrates the "undo" usage of the Memento Pattern.

classOriginator{privateStringstate;// The class could also contain additional data that is not part of the// state saved in the memento.publicvoidset(Stringstate){System.out.println("Originator: Setting state to "+state);this.state=state;}publicMementosaveToMemento(){System.out.println("Originator: Saving to Memento.");returnnewMemento(state);}publicvoidrestoreFromMemento(Mementomemento){state=memento.getSavedState();System.out.println("Originator: State after restoring from Memento: "+state);}publicstaticclassMemento{privatefinalStringstate;privateMemento(StringstateToSave){state=stateToSave;}privateStringgetSavedState(){returnstate;}}}
importjava.util.List;importjava.util.ArrayList;classCaretaker{publicstaticvoidmain(String[]args){List<Originator.Memento>savedStates=newArrayList<Originator.Memento>();Originatororiginator=newOriginator();originator.set("State1");originator.set("State2");savedStates.add(originator.saveToMemento());originator.set("State3");// We can request multiple mementos, and choose which one to roll back to.savedStates.add(originator.saveToMemento());originator.set("State4");originator.restoreFromMemento(savedStates.get(1));}}

The output is:

Originator: Setting state to State1Originator: Setting state to State2Originator: Saving to Memento.Originator: Setting state to State3Originator: Saving to Memento.Originator: Setting state to State4Originator: State after restoring from Memento: State3
Implementation in C#

C# Example

usingSystem;namespaceDoFactory.GangOfFour.Memento.Structural{// MainApp startup class for Structural// Memento Design Pattern.classMainApp{// Entry point into console application.staticvoidMain(){Originatoro=newOriginator();o.State="On";// Store internal stateCaretakerc=newCaretaker();c.Memento=o.CreateMemento();// Continue changing originatoro.State="Off";// Restore saved stateo.SetMemento(c.Memento);// Wait for userConsole.ReadKey();}}// The 'Originator' classclassOriginator{privatestring_state;// PropertypublicstringState{get{return_state;}set{_state=value;Console.WriteLine("State = "+_state);}}// Creates mementopublicMementoCreateMemento(){return(newMemento(_state));}// Restores original statepublicvoidSetMemento(Mementomemento){Console.WriteLine("Restoring state...");State=memento.State;}}// The 'Memento' classclassMemento{privatereadonlystring_state;// ConstructorpublicMemento(stringstate){this._state=state;}// Gets or sets statepublicstringState{get{return_state;}}}// The 'Caretaker' classclassCaretaker{privateMemento_memento;// Gets or sets mementopublicMementoMemento{set{_memento=value;}get{return_memento;}}}}

Another way to implement memento in C#

publicinterfaceIOriginator{IMementoGetState();}publicinterfaceIShape:IOriginator{voidDraw();voidScale(doublescale);voidMove(doubledx,doubledy);}publicinterfaceIMemento{voidRestoreState();}publicclassCircleOriginator:IShape{privateclassCircleMemento:IMemento{privatereadonlydoublex;privatereadonlydoubley;privatereadonlydoubler;privatereadonlyCircleOriginatororiginator;publicCircleMemento(CircleOriginatororiginator){this.originator=originator;x=originator.x;y=originator.y;r=originator.r;}publicvoidRestoreState(){originator.x=x;originator.y=y;originator.r=r;}}doublex;doubley;doubler;publicCircleOriginator(doublex,doubley,doubler){this.x=x;this.y=y;this.r=r;}publicvoidDraw(){Console.WriteLine("Circle with radius {0} at ({1}, {2})",r,x,y);}publicvoidScale(doublescale){r*=scale;}publicvoidMove(doubledx,doubledy){x+=dx;y+=dy;}publicIMementoGetState(){returnnewCircleMemento(this);}}publicclassRectOriginator:IShape{privateclassRectMemento:IMemento{privatereadonlydoublex;privatereadonlydoubley;privatereadonlydoublew;privatereadonlydoubleh;privatereadonlyRectOriginatororiginator;publicRectMemento(RectOriginatororiginator){this.originator=originator;x=originator.x;y=originator.y;w=originator.w;h=originator.h;}publicvoidRestoreState(){originator.x=x;originator.y=y;originator.w=w;originator.h=h;}}doublex;doubley;doublew;doubleh;publicRectOriginator(doublex,doubley,doublew,doubleh){this.x=x;this.y=y;this.w=w;this.h=h;}publicvoidDraw(){Console.WriteLine("Rectangle {0}x{1} at ({2}, {3})",w,h,x,y);}publicvoidScale(doublescale){w*=scale;h*=scale;}publicvoidMove(doubledx,doubledy){x+=dx;y+=dy;}publicIMementoGetState(){returnnewRectMemento(this);}}publicclassCaretaker{publicvoidDraw(IEnumerable<IShape>shapes){foreach(IShapeshapeinshapes){shape.Draw();}}publicvoidMoveAndScale(IEnumerable<IShape>shapes){foreach(IShapeshapeinshapes){shape.Scale(10);shape.Move(3,2);}}publicIEnumerable<IMemento>SaveStates(IEnumerable<IShape>shapes){List<IMemento>states=newList<IMemento>();foreach(IShapeshapeinshapes){states.Add(shape.GetState());}returnstates;}publicvoidRestoreStates(IEnumerable<IMemento>states){foreach(IMementostateinstates){state.RestoreState();}}publicstaticvoidMain(){IShape[]shapes={newRectOriginator(10,20,3,5),newCircleOriginator(5,2,10)};//Outputs:// Rectangle 3x5 at (10, 20)// Circle with radius 10 at (5, 2)Draw(shapes);//Save states of figuresIEnumerable<IMemento>states=SaveStates(shapes);//Change placement of figuresMoveAndScale(shapes);//Outputs:// Rectangle 30x50 at (13, 22)// Circle with radius 100 at (8, 4)Draw(shapes);//Restore old placement of figuresRestoreStates(states);//Outputs:// Rectangle 3x5 at (10, 20)// Circle with radius 10 at (5, 2)Draw(shapes);}}
Implementation in Pascal
{$apptype console}programMemento;usesSysUtils,Classes;typeTMemento=classprivate_state:string;functionGetSavedState:string;publicconstructorCreate(stateToSave:string);propertySavedState:stringreadGetSavedState;end;TOriginator=classprivate_state:string;// The class could also contain additional data that is not part of the// state saved in the memento.procedureSetState(conststate:string);publicfunctionSaveToMemento:TMemento;procedureRestoreFromMemento(Memento:TMemento);propertystate:stringread_statewriteSetState;end;TCaretaker=classprivate_memento:TMemento;publicpropertyMemento:TMementoread_mementowrite_memento;end;{ TMemento }constructorTMemento.Create(stateToSave:string);begin_state:=stateToSave;end;functionTMemento.GetSavedState:string;beginwriteln('restoring state from Memento');result:=_state;end;{ TOriginator }procedureTOriginator.RestoreFromMemento(Memento:TMemento);begin_state:=Memento.SavedState;writeln('Originator: State after restoring from Memento: '+state);end;functionTOriginator.SaveToMemento:TMemento;beginwriteln('Originator: Saving to Memento.');result:=TMemento.Create(state);end;procedureTOriginator.SetState(conststate:string);beginwriteln('Originator: Setting state to '+state);_state:=state;end;varoriginator:TOriginator;c1,c2:TCaretaker;beginoriginator:=TOriginator.Create;originator.SetState('State1');originator.SetState('State2');// Store internal statec1:=TCaretaker.Create();c1.Memento:=originator.SaveToMemento();originator.SetState('State3');// We can request multiple mementos, and choose which one to roll back to.c2:=TCaretaker.Create();c2.Memento:=originator.SaveToMemento();originator.SetState('State4');// Restore saved stateoriginator.RestoreFromMemento(c1.Memento);originator.RestoreFromMemento(c2.Memento);c1.Memento.Free;c1.Free;c2.Memento.Free;c2.Free;originator.Free;end.
Implementation in Scala
importjava.util.Dateimportcommon.patterns.Originator.Mementoimportscala.collection.immutable.TreeMapobjectOriginator{caseclassMemento(x:Int,y:Int,time:Date)}caseclassOriginator(varx:Int,vary:Int){defsetState(x:Int,y:Int){this.x=xthis.y=y}defcreateMemento():Memento=Memento(x,y,newDate())defrestoreFromMemento(restore:Memento){this.x=restore.xthis.y=restore.y}}objectCaretakerextendsApp{varstates:TreeMap[Date,Memento]=newTreeMapvaloriginator=newOriginator(0,0)varmemento=originator.createMemento()states+=(memento.time->memento)Thread.sleep(100)originator.setState(5,4)memento=originator.createMemento()states+=(memento.time->memento)Thread.sleep(100)originator.setState(10,10)memento=originator.createMemento()states+=(memento.time->memento)originator.restoreFromMemento(states(states.drop(1).firstKey))//restore second stateprintln(originator)}

Output:

   Originator(5,4)


Clipboard

To do:
Add more illustrations.


MediatorComputer Science Design Patterns
Memento
Model–view–controller


You have questions about this page?
Ask it here:


Create a new page on this book:


Retrieved from "https://en.wikibooks.org/w/index.php?title=Computer_Science_Design_Patterns/Memento&oldid=3675878"
Category:
Hidden category:

[8]ページ先頭

©2009-2025 Movatter.jp