Memento Page 283 Jason Penny Memento n n

  • Slides: 12
Download presentation
Memento Page 283 Jason Penny

Memento Page 283 Jason Penny

Memento n n Behavioral Pattern Intent: n n Without violating encapsulation, capture and externalize

Memento n n Behavioral Pattern Intent: n n Without violating encapsulation, capture and externalize an object’s internal state so that the object can be restored to this state later Sometimes its necessary to record the internal state of an object n n When implementing checkpoints When implementing undo mechanisms for both backing out of tentative operations and for recovering from errors

Problem: n We don’t want objects to expose their details to provide save and

Problem: n We don’t want objects to expose their details to provide save and restore functionality, this would violate encapsulation n A memento is a copy of the minimal information required to rebuild the object’s state, so large objects can be rebuilt using smaller mementos

Memento Class Diagram Caretaker Originator Memento create. Memento() set. Memento() get. State() state return

Memento Class Diagram Caretaker Originator Memento create. Memento() set. Memento() get. State() state return new Memento(state) state = memento->get. State()

Memento Interaction Diagram a. Caretaker an. Originator create. Memento() new Memento set. State() set.

Memento Interaction Diagram a. Caretaker an. Originator create. Memento() new Memento set. State() set. Memento(a. Memento) get. State() a. Memento

Supporting Undo n n Sometimes reversing the actions on an object does not return

Supporting Undo n n Sometimes reversing the actions on an object does not return the object to its previous state Consider a connected line class that insures that a line always connects the two rectangles it is associated with

Reversing the Operations n n In this case, reversing the operation produces a different

Reversing the Operations n n In this case, reversing the operation produces a different result than we started with Using a memento to save and restore the state solves this problem

Implementation class State; class Originator { public: Memento* Create. Memento(); void Set. Memento( const

Implementation class State; class Originator { public: Memento* Create. Memento(); void Set. Memento( const Memento* ); //. . . private: State* _state; // internal data structures //. . . }; class Memento { public: // narrow public interface virtual ~Memento(); private: // private members accessible // only to Originator friend class Originator; Memento(); void Set. State( State* ); State* Get. State(); //. . . private: State* _state; //. . . };

Summary: Consequences Preserving encapsulation boundaries n It simplifies Originator n Using mementos might be

Summary: Consequences Preserving encapsulation boundaries n It simplifies Originator n Using mementos might be expensive n Defining narrow and wide interfaces n Hidden costs in caring for mementos n

Sample Code class Graphic; // base class for graphical objects in the graphical editor

Sample Code class Graphic; // base class for graphical objects in the graphical editor class Move. Command { public: Move. Command( Graphic* target, const Point& delta ); void Execute(); void Unexecute(); private: Constraint. Solver. Memento* _state; Point _delta; Graphic* target; }

Sample Code Continued class Constraint. Solver { public: static Constraint. Solver* Instance(); void Solve();

Sample Code Continued class Constraint. Solver { public: static Constraint. Solver* Instance(); void Solve(); void Add. Constraint( Graphic* start. Connection, Graphic* end. Connection ); void Remove. Connection( Graphic* start. Connection, Graphic* end. Connection ); Constraint. Solver. Memento* Create. Memento(); void Set. Memento( Constaint. Solver. Memento* ); private: // nontrivial state and operations for enforcing // connectivity semantics };

void Move. Command: : Execute() { Constraint. Solver* solver = Constraint. Solver: : Instance();

void Move. Command: : Execute() { Constraint. Solver* solver = Constraint. Solver: : Instance(); _state = solver->Create. Memento(); // create a Memento _target->Move( _delta ); solver->Solve(); } void Move. Command: : Unexecute() { Constraint. Solver* solver = Constraint. Solver: : Instance(); _target->Move( -_delta ); solver->Set. Memento( _state ); // restore solver state solver->Solve(); }