Memento comes under Behavioral design pattern.
It provides a way to capture the internal state of an object and restore the object to its previous state
at some point later just like undo operation.
Behaviour & Advantages
Captures the snapshot state of an object.
Restores object to its previous state from one of the available snapshot states.
Memento
It stores the internal state of Originator.
Shouldn't allow any other object to modify saved state.
Originator may sign the Memento for verification during restore.
Originator
It creates a Memento by saving its internal state.
Uses the same Memento for restore at later point.
Caretaker
It keeps track of Mementos until its required during restore.
Caretaker shouldn't modify the saved state of Memento.
Check the createMemento method of Originator which saves the internal
state of Originator to a newly created memento and seals the object with its signature.
In restoreMemento method the signature set to memento is verified before restoring Originator state.
Originator implementation is shown below,
public void setState(String state) { this.state = state;
}
public Memento createMemento() {
/**
* Create a Memento and mark the signature.
*/
Memento memento = new Memento(state);
memento.setSignature(getSignature()); return memento;
}
public void restoreMemento(Memento memento) {
/**
* Verify the Memento signature set previously.
*/ if (getSignature().equals(memento.getSignature())) { this.state = memento.getState();
} else { throw new IllegalArgumentException("Invalid memento : " + memento);
}
}
/**
* Generate unique signature for this instance of Originator.
*/ private String getSignature() { if (signature == null) {
signature = "Originator@" +
System.currentTimeMillis() +
"@" + (Math.random() * 1729);
} return signature;
}
public String toString() { return "Originator[" + state + "]";
}
/**
* Don't let others modify the 'Memento'
* except the Originator that produced it.
*/ public static class Memento {
The saveState method of Caretaker requests a memento from Originator and
queues it for later restore. The restoreState method restores the Originator
to its most recently saved state. Caretaker implementation is shown below,
Originator originator = new Originator();
Caretaker caretaker = new Caretaker(originator);
/**
* Save state
*/
originator.setState("SERVER_STARTING");
System.out.println("Current State : " + originator);
caretaker.saveState();
originator.setState("SERVER_RUNNING");
System.out.println("Current State : " + originator);
caretaker.saveState();
originator.setState("SERVER_ABOUT_TO_STOP");
System.out.println("Current State : " + originator);
caretaker.saveState();
originator.setState("SERVER_STOPPED");
System.out.println("Current State : " + originator);
caretaker.saveState();
System.out.println();
/**
* Restore state
*/
caretaker.restoreState();
System.out.println("Restored State : " + originator);
caretaker.restoreState();
System.out.println("Restored State : " + originator);
caretaker.restoreState();
System.out.println("Restored State : " + originator);
caretaker.restoreState();
System.out.println("Restored State : " + originator);
}
}
It gives the following output,
Current State : Originator[SERVER_STARTING]
Current State : Originator[SERVER_RUNNING]
Current State : Originator[SERVER_ABOUT_TO_STOP]
Current State : Originator[SERVER_STOPPED]
Restored State : Originator[SERVER_STOPPED]
Restored State : Originator[SERVER_ABOUT_TO_STOP]
Restored State : Originator[SERVER_RUNNING]
Restored State : Originator[SERVER_STARTING]