Improved encapsulation of the Memento pattern by moving the

StarMementoInternal class to inner class of Star.
This commit is contained in:
Ilkka Seppala 2015-05-30 12:36:53 +03:00
parent 72bc96f81b
commit 703ebd3e20
7 changed files with 142 additions and 143 deletions

View File

@ -353,7 +353,7 @@ A programming idiom is a means of expressing a recurring construct in one or mor
## <a name="memento">Memento</a> [&#8593;](#list-of-design-patterns)
**Intent:** Without violating encapsulation, capture and externalize an object's internal state so that the object can be restored to this state later.
![alt text](https://github.com/iluwatar/java-design-patterns/blob/master/memento/etc/memento_1.png "Memento")
![alt text](https://github.com/iluwatar/java-design-patterns/blob/master/memento/etc/memento.png "Memento")
**Applicability:** Use the Memento pattern when
* a snapshot of an object's state must be saved so that it can be restored to that state later, and

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

BIN
memento/etc/memento.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -1,65 +1,65 @@
<?xml version="1.0" encoding="UTF-8"?>
<class-diagram version="1.1.7" icons="true" always-add-relationships="false" generalizations="true" realizations="true"
associations="true" dependencies="false" nesting-relationships="true">
<class-diagram version="1.1.8" icons="true" automaticImage="PNG" always-add-relationships="false" generalizations="true"
realizations="true" associations="true" dependencies="false" nesting-relationships="true">
<class id="1" language="java" name="com.iluwatar.Star" project="memento"
file="/memento/src/main/java/com/iluwatar/Star.java" binary="false" corner="BOTTOM_RIGHT">
<position height="-1" width="-1" x="383" y="159"/>
<position height="-1" width="-1" x="301" y="385"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</class>
<class id="2" language="java" name="com.iluwatar.StarMementoInternal" project="memento"
file="/memento/src/main/java/com/iluwatar/StarMementoInternal.java" binary="false" corner="BOTTOM_RIGHT">
<position height="-1" width="-1" x="697" y="141"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</class>
<enumeration id="3" language="java" name="com.iluwatar.StarType" project="memento"
<enumeration id="2" language="java" name="com.iluwatar.StarType" project="memento"
file="/memento/src/main/java/com/iluwatar/StarType.java" binary="false" corner="BOTTOM_RIGHT">
<position height="-1" width="-1" x="533" y="429"/>
<position height="-1" width="-1" x="301" y="911"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</enumeration>
<interface id="4" language="java" name="com.iluwatar.StarMemento" project="memento"
<interface id="3" language="java" name="com.iluwatar.StarMemento" project="memento"
file="/memento/src/main/java/com/iluwatar/StarMemento.java" binary="false" corner="BOTTOM_RIGHT">
<position height="-1" width="-1" x="536" y="-17"/>
<position height="-1" width="-1" x="103" y="830"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</interface>
<dependency id="5">
<class id="4" language="java" name="com.iluwatar.Star.StarMementoInternal" project="memento"
file="/memento/src/main/java/com/iluwatar/Star.java" binary="false" corner="BOTTOM_RIGHT">
<position height="-1" width="-1" x="103" y="639"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</class>
<association id="5">
<end type="SOURCE" refId="1" navigable="false">
<attribute id="6" name="type"/>
<multiplicity id="7" minimum="0" maximum="1"/>
</end>
<end type="TARGET" refId="2" navigable="true"/>
<display labels="true" multiplicity="true"/>
</association>
<association id="8">
<end type="SOURCE" refId="4" navigable="false">
<attribute id="9" name="type"/>
<multiplicity id="10" minimum="0" maximum="1"/>
</end>
<end type="TARGET" refId="2" navigable="true"/>
<display labels="true" multiplicity="true"/>
</association>
<nesting id="11">
<end type="SOURCE" refId="1"/>
<end type="TARGET" refId="4"/>
</dependency>
<association id="6">
<end type="SOURCE" refId="1" navigable="false">
<attribute id="7" name="type"/>
<multiplicity id="8" minimum="0" maximum="1"/>
</end>
<end type="TARGET" refId="3" navigable="true"/>
<display labels="true" multiplicity="true"/>
</association>
<association id="9">
<end type="SOURCE" refId="2" navigable="false">
<attribute id="10" name="type"/>
<multiplicity id="11" minimum="0" maximum="1"/>
</end>
<end type="TARGET" refId="3" navigable="true"/>
<display labels="true" multiplicity="true"/>
</association>
</nesting>
<realization id="12">
<end type="SOURCE" refId="2"/>
<end type="TARGET" refId="4"/>
<end type="SOURCE" refId="4"/>
<end type="TARGET" refId="3"/>
</realization>
<classifier-display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

View File

@ -1,69 +1,105 @@
package com.iluwatar;
/**
*
* Star uses "mementos" to store and restore state.
*
*/
public class Star {
private StarType type;
private int ageYears;
private int massTons;
public Star(StarType startType, int startAge, int startMass) {
this.type = startType;
this.ageYears = startAge;
this.massTons = startMass;
}
public void timePasses() {
ageYears *= 2;
massTons *= 8;
switch (type) {
case RED_GIANT:
type = StarType.WHITE_DWARF;
break;
case SUN:
type = StarType.RED_GIANT;
break;
case SUPERNOVA:
type = StarType.DEAD;
break;
case WHITE_DWARF:
type = StarType.SUPERNOVA;
break;
case DEAD:
ageYears *= 2;
massTons = 0;
break;
default:
break;
}
}
StarMemento getMemento() {
StarMementoInternal state = new StarMementoInternal();
state.setAgeYears(ageYears);
state.setMassTons(massTons);
state.setType(type);
return state;
}
void setMemento(StarMemento memento) {
StarMementoInternal state = (StarMementoInternal) memento;
this.type = state.getType();
this.ageYears = state.getAgeYears();
this.massTons = state.getMassTons();
}
@Override
public String toString() {
return String.format("%s age: %d years mass: %d tons", type.toString(),
ageYears, massTons);
}
}
package com.iluwatar;
/**
*
* Star uses "mementos" to store and restore state.
*
*/
public class Star {
private StarType type;
private int ageYears;
private int massTons;
public Star(StarType startType, int startAge, int startMass) {
this.type = startType;
this.ageYears = startAge;
this.massTons = startMass;
}
public void timePasses() {
ageYears *= 2;
massTons *= 8;
switch (type) {
case RED_GIANT:
type = StarType.WHITE_DWARF;
break;
case SUN:
type = StarType.RED_GIANT;
break;
case SUPERNOVA:
type = StarType.DEAD;
break;
case WHITE_DWARF:
type = StarType.SUPERNOVA;
break;
case DEAD:
ageYears *= 2;
massTons = 0;
break;
default:
break;
}
}
StarMemento getMemento() {
StarMementoInternal state = new StarMementoInternal();
state.setAgeYears(ageYears);
state.setMassTons(massTons);
state.setType(type);
return state;
}
void setMemento(StarMemento memento) {
StarMementoInternal state = (StarMementoInternal) memento;
this.type = state.getType();
this.ageYears = state.getAgeYears();
this.massTons = state.getMassTons();
}
@Override
public String toString() {
return String.format("%s age: %d years mass: %d tons", type.toString(),
ageYears, massTons);
}
/**
*
* StarMemento implementation
*
*/
private static class StarMementoInternal implements StarMemento {
private StarType type;
private int ageYears;
private int massTons;
public StarType getType() {
return type;
}
public void setType(StarType type) {
this.type = type;
}
public int getAgeYears() {
return ageYears;
}
public void setAgeYears(int ageYears) {
this.ageYears = ageYears;
}
public int getMassTons() {
return massTons;
}
public void setMassTons(int massTons) {
this.massTons = massTons;
}
}
}

View File

@ -1,37 +0,0 @@
package com.iluwatar;
/**
*
* Internal interface to memento.
*
*/
public class StarMementoInternal implements StarMemento {
private StarType type;
private int ageYears;
private int massTons;
public StarType getType() {
return type;
}
public void setType(StarType type) {
this.type = type;
}
public int getAgeYears() {
return ageYears;
}
public void setAgeYears(int ageYears) {
this.ageYears = ageYears;
}
public int getMassTons() {
return massTons;
}
public void setMassTons(int massTons) {
this.massTons = massTons;
}
}