备忘录模式

备忘录模式UML类图

备忘录模式UML类图

备忘录模式java实现

/**
* StarType enumeration.
*/
public enum StarType {

SUN("sun"), RED_GIANT("red giant"), WHITE_DWARF("white dwarf"), SUPERNOVA("supernova"), DEAD(
"dead star"), UNDEFINED("");

private String title;

StarType(String title) {
this.title = title;
}

@Override
public String toString() {
return title;
}
}

/**
* External interface to memento.
*/
public interface StarMemento {

}

/**
* Star uses "mementos" to store and restore state.
*/
public class Star {

private StarType type;
private int ageYears;
private int massTons;

/**
* Constructor.
*/
public Star(StarType startType, int startAge, int startMass) {
this.type = startType;
this.ageYears = startAge;
this.massTons = startMass;
}

/**
* Makes time pass for the star.
*/
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;
}
}
}

/**
* The Memento pattern is a software design pattern that provides the ability to restore an object
* to its previous state (undo via rollback).
*
* <p>The Memento pattern is implemented with three objects: the originator, a caretaker and a
* memento. The originator is some object that has an internal state. The caretaker is going to do
* something to the originator, but wants to be able to undo the change. The caretaker first asks
* the originator for a memento object. Then it does whatever operation (or sequence of operations)
* it was going to do. To roll back to the state before the operations, it returns the memento
* object to the originator. The memento object itself is an opaque object (one which the caretaker
* cannot, or should not, change). When using this pattern, care should be taken if the originator
* may change other objects or resources - the memento pattern operates on a single object.
*
* <p>In this example the object ({@link Star}) gives out a "memento" ({@link StarMemento}) that
* contains the state of the object. Later on the memento can be set back to the object restoring
* the state.
Memento模式是一种软件设计模式,它提供了将对象恢复到其先前状态(通过回滚撤消)的能力。
<p> Memento模式由三个对象实现:发起者,看守者和memento。发起者是一些具有内部状态的对象。管理员将对发起者进行某些操作,但希望能够撤消更改。看守首先要向创建者索要纪念品。然后,它执行将要执行的任何操作(或操作序列)。要回滚到操作之前的状态,它将纪念对象返回给发起者。纪念品对象本身是不透明的对象(看守不能更改或不应该更改的对象)。使用此模式时,请注意发起者是否可以更改其他对象或资源-记忆模式可在单个对象上运行。
<p>在此示例中,对象({@link Star})给出一个包含对象状态的“备忘录”({@link StarMemento})。稍后,可以将备忘录设置回恢复状态的对象。
*/
public class App {

private static final Logger LOGGER = LoggerFactory.getLogger(App.class);

/**
* Program entry point.
*/
public static void main(String[] args) {
Stack<StarMemento> states = new Stack<>();

Star star = new Star(StarType.SUN, 10000000, 500000);
LOGGER.info(star.toString());
states.add(star.getMemento());
star.timePasses();
LOGGER.info(star.toString());
states.add(star.getMemento());
star.timePasses();
LOGGER.info(star.toString());
states.add(star.getMemento());
star.timePasses();
LOGGER.info(star.toString());
states.add(star.getMemento());
star.timePasses();
LOGGER.info(star.toString());
while (states.size() > 0) {
star.setMemento(states.pop());
LOGGER.info(star.toString());
}
}
}