X Tutup
Skip to content

Commit b907a2a

Browse files
committed
iluwatar#590 add explanation for Memento
1 parent 467f647 commit b907a2a

File tree

1 file changed

+171
-2
lines changed

1 file changed

+171
-2
lines changed

memento/README.md

Lines changed: 171 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,177 @@ tags:
1212
Token
1313

1414
## Intent
15-
Without violating encapsulation, capture and externalize an
16-
object's internal state so that the object can be restored to this state later.
15+
Without violating encapsulation, capture and externalize an object's internal state so that the object can be restored
16+
to this state later.
17+
18+
## Explanation
19+
Real world example
20+
21+
> We are working on astrology application where we need to analyze star properties over time. We are creating snapshots of star state using Memento pattern.
22+
23+
In plain words
24+
25+
> Memento pattern captures object internal state making it easy to store and restore objects in any point of time.
26+
27+
Wikipedia says
28+
29+
> The memento pattern is a software design pattern that provides the ability to restore an object to its previous state (undo via rollback).
30+
31+
**Programmatic Example**
32+
33+
Let's first define the types of stars we are capable to handle.
34+
35+
```java
36+
public enum StarType {
37+
38+
SUN("sun"), RED_GIANT("red giant"), WHITE_DWARF("white dwarf"), SUPERNOVA("supernova"), DEAD(
39+
"dead star"), UNDEFINED("");
40+
41+
private String title;
42+
43+
StarType(String title) {
44+
this.title = title;
45+
}
46+
47+
@Override
48+
public String toString() {
49+
return title;
50+
}
51+
}
52+
```
53+
54+
Next let's jump straight to the essentials. Here's the star class along with the mementos that we need manipulate.
55+
56+
```java
57+
public interface StarMemento {
58+
}
59+
60+
public class Star {
61+
62+
private StarType type;
63+
private int ageYears;
64+
private int massTons;
65+
66+
public Star(StarType startType, int startAge, int startMass) {
67+
this.type = startType;
68+
this.ageYears = startAge;
69+
this.massTons = startMass;
70+
}
71+
72+
public void timePasses() {
73+
ageYears *= 2;
74+
massTons *= 8;
75+
switch (type) {
76+
case RED_GIANT:
77+
type = StarType.WHITE_DWARF;
78+
break;
79+
case SUN:
80+
type = StarType.RED_GIANT;
81+
break;
82+
case SUPERNOVA:
83+
type = StarType.DEAD;
84+
break;
85+
case WHITE_DWARF:
86+
type = StarType.SUPERNOVA;
87+
break;
88+
case DEAD:
89+
ageYears *= 2;
90+
massTons = 0;
91+
break;
92+
default:
93+
break;
94+
}
95+
}
96+
97+
StarMemento getMemento() {
98+
99+
StarMementoInternal state = new StarMementoInternal();
100+
state.setAgeYears(ageYears);
101+
state.setMassTons(massTons);
102+
state.setType(type);
103+
return state;
104+
}
105+
106+
void setMemento(StarMemento memento) {
107+
108+
StarMementoInternal state = (StarMementoInternal) memento;
109+
this.type = state.getType();
110+
this.ageYears = state.getAgeYears();
111+
this.massTons = state.getMassTons();
112+
}
113+
114+
@Override
115+
public String toString() {
116+
return String.format("%s age: %d years mass: %d tons", type.toString(), ageYears, massTons);
117+
}
118+
119+
private static class StarMementoInternal implements StarMemento {
120+
121+
private StarType type;
122+
private int ageYears;
123+
private int massTons;
124+
125+
public StarType getType() {
126+
return type;
127+
}
128+
129+
public void setType(StarType type) {
130+
this.type = type;
131+
}
132+
133+
public int getAgeYears() {
134+
return ageYears;
135+
}
136+
137+
public void setAgeYears(int ageYears) {
138+
this.ageYears = ageYears;
139+
}
140+
141+
public int getMassTons() {
142+
return massTons;
143+
}
144+
145+
public void setMassTons(int massTons) {
146+
this.massTons = massTons;
147+
}
148+
}
149+
}
150+
```
151+
152+
And finally here's how we use the mementos to store and restore star states.
153+
154+
```java
155+
Stack<StarMemento> states = new Stack<>();
156+
Star star = new Star(StarType.SUN, 10000000, 500000);
157+
LOGGER.info(star.toString());
158+
states.add(star.getMemento());
159+
star.timePasses();
160+
LOGGER.info(star.toString());
161+
states.add(star.getMemento());
162+
star.timePasses();
163+
LOGGER.info(star.toString());
164+
states.add(star.getMemento());
165+
star.timePasses();
166+
LOGGER.info(star.toString());
167+
states.add(star.getMemento());
168+
star.timePasses();
169+
LOGGER.info(star.toString());
170+
while (states.size() > 0) {
171+
star.setMemento(states.pop());
172+
LOGGER.info(star.toString());
173+
}
174+
175+
// sun age: 10000000 years mass: 500000 tons
176+
// red giant age: 20000000 years mass: 4000000 tons
177+
// white dwarf age: 40000000 years mass: 32000000 tons
178+
// supernova age: 80000000 years mass: 256000000 tons
179+
// dead star age: 160000000 years mass: 2048000000 tons
180+
// supernova age: 80000000 years mass: 256000000 tons
181+
// white dwarf age: 40000000 years mass: 32000000 tons
182+
// red giant age: 20000000 years mass: 4000000 tons
183+
// sun age: 10000000 years mass: 500000 tons
184+
```
185+
17186

18187
## Class diagram
19188
![alt text](./etc/memento.png "Memento")

0 commit comments

Comments
 (0)
X Tutup