Skip to content

Commit 1b97de7

Browse files
committed
add Memento pattern
1 parent 555f1c9 commit 1b97de7

File tree

2 files changed

+134
-0
lines changed

2 files changed

+134
-0
lines changed

memento/Memento.cpp

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
/*
2+
* C++ Design Patterns: Memento
3+
* Author: Jakub Vojvoda [github.com/JakubVojvoda]
4+
* 2016
5+
*
6+
* Source code is licensed under MIT License
7+
* (for more details see LICENSE)
8+
*
9+
*/
10+
11+
#include <iostream>
12+
#include <vector>
13+
14+
/*
15+
* Memento
16+
* stores internal state of the Originator object and protects
17+
* against access by objects other than the originator
18+
*/
19+
class Memento {
20+
private:
21+
// accessible only to Originator
22+
friend class Originator;
23+
24+
Memento(int s)
25+
: state(s) {}
26+
27+
void setState(int s) {
28+
state = s;
29+
}
30+
31+
int getState() {
32+
return state;
33+
}
34+
// ...
35+
36+
private:
37+
int state;
38+
// ...
39+
};
40+
41+
/*
42+
* Originator
43+
* creates a memento containing a snapshot of its current internal
44+
* state and uses the memento to restore its internal state
45+
*/
46+
class Originator {
47+
public:
48+
// implemented only for printing purpose
49+
void setState(int s) {
50+
state = s;
51+
}
52+
53+
// implemented only for printing purpose
54+
int getState() {
55+
return state;
56+
}
57+
58+
void setMemento(Memento *m) {
59+
state = m->getState();
60+
}
61+
62+
Memento *createMemento() {
63+
return new Memento(state);
64+
}
65+
66+
private:
67+
int state;
68+
// ...
69+
};
70+
71+
/*
72+
* CareTaker
73+
* is responsible for the memento's safe keeping
74+
*/
75+
class CareTaker {
76+
public:
77+
CareTaker(Originator *o)
78+
: originator(o) {}
79+
80+
~CareTaker() {
81+
for (unsigned int i = 0; i < history.size(); i++) {
82+
delete history.at(i);
83+
}
84+
history.clear();
85+
}
86+
87+
void save() {
88+
history.push_back(originator->createMemento());
89+
}
90+
91+
void undo() {
92+
originator->setMemento(history.front());
93+
history.pop_back();
94+
}
95+
// ...
96+
97+
private:
98+
Originator *originator;
99+
std::vector<Memento *> history;
100+
// ...
101+
};
102+
103+
104+
int main()
105+
{
106+
Originator *originator = new Originator;
107+
CareTaker *caretaker = new CareTaker(originator);
108+
109+
originator->setState(1);
110+
caretaker->save();
111+
std::cout << "Set state: " << originator->getState() << std::endl;
112+
113+
originator->setState(2);
114+
caretaker->save();
115+
std::cout << "Set state: " << originator->getState() << std::endl;
116+
117+
caretaker->undo();
118+
std::cout << "Undo state: " << originator->getState() << std::endl;
119+
120+
delete originator;
121+
delete caretaker;
122+
123+
return 0;
124+
}

memento/README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
## Memento
2+
3+
Memento without violating encapsulation, captures and externalizes an object's internal
4+
state so that the object can be restored to this state later. The pattern has behavioral
5+
purpose and applies to the objects.
6+
7+
### When to use
8+
9+
* a snapshot of an object's state must be saved so that it can be restored to that state later
10+
* a direct interface to obtaining the state would expose implementation details and break the object's encapsulation

0 commit comments

Comments
 (0)