diff --git a/memento/Memento.cpp b/memento/Memento.cpp new file mode 100644 index 0000000..59feb2f --- /dev/null +++ b/memento/Memento.cpp @@ -0,0 +1,124 @@ +/* + * C++ Design Patterns: Memento + * Author: Jakub Vojvoda [github.com/JakubVojvoda] + * 2016 + * + * Source code is licensed under MIT License + * (for more details see LICENSE) + * + */ + +#include +#include + +/* + * Memento + * stores internal state of the Originator object and protects + * against access by objects other than the originator + */ +class Memento { +private: + // accessible only to Originator + friend class Originator; + + Memento(int s) + : state(s) {} + + void setState(int s) { + state = s; + } + + int getState() { + return state; + } + // ... + +private: + int state; + // ... +}; + +/* + * Originator + * creates a memento containing a snapshot of its current internal + * state and uses the memento to restore its internal state + */ +class Originator { +public: + // implemented only for printing purpose + void setState(int s) { + state = s; + } + + // implemented only for printing purpose + int getState() { + return state; + } + + void setMemento(Memento *m) { + state = m->getState(); + } + + Memento *createMemento() { + return new Memento(state); + } + +private: + int state; + // ... +}; + +/* + * CareTaker + * is responsible for the memento's safe keeping + */ +class CareTaker { +public: + CareTaker(Originator *o) + : originator(o) {} + + ~CareTaker() { + for (unsigned int i = 0; i < history.size(); i++) { + delete history.at(i); + } + history.clear(); + } + + void save() { + history.push_back(originator->createMemento()); + } + + void undo() { + originator->setMemento(history.front()); + history.pop_back(); + } + // ... + +private: + Originator *originator; + std::vector history; + // ... +}; + + +int main() +{ + Originator *originator = new Originator; + CareTaker *caretaker = new CareTaker(originator); + + originator->setState(1); + caretaker->save(); + std::cout << "Set state: " << originator->getState() << std::endl; + + originator->setState(2); + caretaker->save(); + std::cout << "Set state: " << originator->getState() << std::endl; + + caretaker->undo(); + std::cout << "Undo state: " << originator->getState() << std::endl; + + delete originator; + delete caretaker; + + return 0; +} diff --git a/memento/README.md b/memento/README.md new file mode 100644 index 0000000..f822499 --- /dev/null +++ b/memento/README.md @@ -0,0 +1,10 @@ +## Memento + +Memento without violating encapsulation, captures and externalizes an object's internal +state so that the object can be restored to this state later. The pattern has behavioral +purpose and applies to the objects. + +### When to use + +* a snapshot of an object's state must be saved so that it can be restored to that state later +* a direct interface to obtaining the state would expose implementation details and break the object's encapsulation \ No newline at end of file