7
Behavioral Pattern: Memento Chapter 5 – Page 1 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

Behavioral Pattern: Memento

  • Upload
    alyson

  • View
    89

  • Download
    0

Embed Size (px)

DESCRIPTION

Behavioral Pattern: Memento. Chapter 5 – Page 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. - PowerPoint PPT Presentation

Citation preview

Page 1: Behavioral Pattern: Memento

Behavioral Pattern: MementoChapter 5 – Page 1Objects 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.

Page 2: Behavioral Pattern: Memento

The Memento PatternChapter 5 – Page 2The 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.

Originatorstate

setMemento(in Memento m)createMemento()

Caretaker

Mementostate

getState()setState()

+memento

setMemento(in Memento m):

state = m.getState()

createMemento:

return new Memento(state)

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.

Page 3: Behavioral Pattern: Memento

Chapter 5 – Page 3Non-Software Example: Car RadioThe 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.

DriverfrequencySetting

pressButton()createPreset()

PresetRadioButtonfrequencySetting

getFrequencySetting()setFrequencySetting()

Radio+memento

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 radiofrequencies of their favorite stations. The preset buttons store the information so that the tuning can be restored.

Page 4: Behavioral Pattern: Memento

Chapter 5 – Page 4Stack Memento Code in C++#include <iostream>

#include <string>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]; }};

Page 5: Behavioral Pattern: Memento

Chapter 5 – Page 5

// 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 < mem->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;};

Page 6: Behavioral Pattern: Memento

Chapter 5 – Page 6// 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;}

Page 7: Behavioral Pattern: Memento

Memento Pattern AdvantagesChapter 5 – Page 7• 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.