Presentation is loading. Please wait.

Presentation is loading. Please wait.

Behavioral Pattern: Memento C h a p t e r 5 – P a g e 179 Objects frequently expose only some of their internal state using public methods, but there.

Similar presentations


Presentation on theme: "Behavioral Pattern: Memento C h a p t e r 5 – P a g e 179 Objects frequently expose only some of their internal state using public methods, but there."— Presentation transcript:

1

2 Behavioral Pattern: Memento C h a p t e r 5 – P a g e 179 Objects frequently expose only some of their internal state using public methods, but there are times when the entire state of an object needs to be saved because it might need to be restored later. In some cases, enough information could be obtained from the public interfaces to save and restore that data. In other cases, information that is not readily available needs to be saved. This sort of information saving and restoration is common in systems that need to support Undo commands. The Memento Pattern makes it possible to save and restore a previous state without making the object itself take care of this task, and without violating encapsulation.

3 The Memento Pattern C h a p t e r 5 – P a g e 180 The Originator creates a Memento containing a snapshot of its internal state, and uses the Memento to restore its internal state. The Memento stores as much or as little of the Originator’s internal state as necessary, at the Originator’s discretion, and protects against access by objects other than the Originator. The Caretaker is responsible for the Memento’s safekeeping, but never operates on or accesses the Memento’s contents. Mementos have effectively two interfaces. The Caretaker sees a narrow interface to the Memento -- it can only pass the Memento to the other objects. In contrast, the Originator sees a wide interface, one that lets it access all of the data necessary to restore itself to its previous state. Ideally, only the Originator that produces the Memento would be permitted to access the Memento's internal state.

4 C h a p t e r 5 – P a g e 181 Non-Software Example: Car Radio The driver (the Originator) sets the preset button and uses it to restore the previous state of the radio tuning. The preset radio button (the Memento) allows the radio to be restored to its desired state with a single button push. The radio (the Caretaker) provides access to the button, but is not capable of changing its state. The button eliminates the need for the drivers to memorize the radio frequencies of their favorite stations. The preset buttons store the information so that the tuning can be restored.

5 C h a p t e r 5 – P a g e 182 Stack Memento Code in C++ #include using namespace std; // The Memento takes a snapshot of the complete // contents of the stack, saving them in an array. class Memento { friend class Stack; public: ~Memento() { delete items; } private: int *items, size; Memento( int* list, int nbrValues ) { size = nbrValues; items = new int[size]; for (int i = 0; i < size; i++) items[i] = list[i]; } };

6 C h a p t e r 5 – P a g e 183 // The stack is the Originator. class Stack { public: Stack() { topIndex = -1; } void push( int in ) { items[++topIndex] = in; } int pop() { return items[topIndex--]; } bool isEmpty() { return topIndex == -1; } Memento* checkPoint() { return new Memento( items, topIndex+1 ); } void rollBack( Memento* mem ) { topIndex = mem->size-1; for (int i = 0; i size; i++) items[i] = mem->items[i]; } friend ostream& operator << ( ostream &output, const Stack &stk ) { string buf( "[ " ); for (int i = 0; i < stk.topIndex+1; i++) { buf += stk.items[i] + 48; buf += ' '; } buf += ']'; return output << buf; } private: int items[10], topIndex; };

7 C h a p t e r 5 – P a g e 184 // The main function is the Caretaker. void main() { Stack stk; int i; for (i = 0; i < 5; i++) stk.push(i); cout << "Original Stack: " << stk << endl; Memento* firstMemento = stk.checkPoint(); cout << "First Memento Created." << endl << endl; for (i = 5; i < 10; i++) stk.push(i); cout << "Revised Stack: " << stk << endl; Memento* secondMemento = stk.checkPoint(); cout << "Second Memento created." << endl << endl; cout << "Emptying Stack: "; while (!stk.isEmpty()) cout << stk.pop() << ' '; cout << endl; cout << "Emptied Stack: " << stk << endl << endl; stk.rollBack( secondMemento ); cout << "Stack After Second Memento Restored: " << stk << endl << endl; stk.rollBack( firstMemento ); cout << "Stack After First Memento Restored: " << stk << endl << endl; cout << "Emptying Stack: "; while (!stk.isEmpty()) cout << stk.pop() << ' '; cout << endl; delete firstMemento; delete secondMemento; }

8 Memento Pattern Advantages C h a p t e r 5 – P a g e 185 If all of the information describing an object is available in public variables, it is not that difficult to save them in some external store. However, making these data public makes the entire system vulnerable to change by external program code, when we usually expect data inside an object to be private and encapsulated from the outside world. The Memento Pattern attempts to solve this problem by having privileged access to the state of the object being saved. Other objects have only a more restricted access to the object, thus preserving their encapsulation. While supporting undo/redo operations is one significant use of the Memento Pattern, Mementos are also used in database transactions, in which they save the state of data in a transaction where it is necessary to restore the data if the transaction fails or is incomplete.


Download ppt "Behavioral Pattern: Memento C h a p t e r 5 – P a g e 179 Objects frequently expose only some of their internal state using public methods, but there."

Similar presentations


Ads by Google