Evaluating Software Design Patterns
— the "Gang of Four" patterns implemented in Java 6

@Pattern(name="Memento", scope=Object, purpose=Behavioural, participants={"Memento","Originator","Caretaker"})

Package dk.rode.thesis.memento

Implementations and examples of the Memento design pattern [Gamma95, p.283].


Interface Summary
MemorizableSequence<E> A memorizable sequence can memorise its internal state at a given time and have it restored again later by using mementos.

Class Summary
GuardedSequenceMemento<E> A guarded sequence memento offer the same functionality as SequenceMemento, but enforce access rules to ensure that only a (memorizable) sequence can set or get the memento state.
Main Memento tests.
MemorizableEnglishAlphabetSequence A memorizable alphabet sequence for letters in the English alphabet, i.e.
RangeSequence A range sequence represents a positive Integer value that is increased with each call to RangeSequence.next(), which can be reversed to deliver previous values as well unless unbounded.
SequenceMemento<E> A sequence memento represents a snap-shot of a given sequence at the time the SequenceMemento.SequenceMemento(Sequence) constructor or the SequenceMemento.setSequence(Sequence) method was invoked.

Exception Summary
MemorizableException A memorizable exception is thrown in case a memorizable sequence cannot be updated by a given sequence memento.

Package dk.rode.thesis.memento Description

Implementations and examples of the Memento design pattern [Gamma95, p.283].


Here, the Memento participant is represented by the SequenceMemento interface, which is applicable to Sequence objects only.

The Originator participant is represented by any MemorizableSequence implementation. Two specific implementations are defined in this package, namely RangeSequence and MemorizableEnglishAlphabetSequence.

The test application, i.e. the Main class, acts as the Caretaker participant.

UML Class Diagram:

Implementation notes:
Internally, sequence mementos utilise the Prototype pattern to save the sequence state.

All memento functionality has to be declared public if it must be used outside this package. It cannot have "two interfaces" in Java, a narrow (public) and a wide (using friends to access private part), as described by Gamma et al. [Gamma95, p.285-287]. This implementation therefore divides the memento functionality into two interfaces, namely SequenceMemento (private parts of wide) and MemorizableSequence (narrow, public). However, the state methods SequenceMemento.setSequence(Sequence), SequenceMemento.getSequence(), and SequenceMemento.current() still have to be public. To enforce an access check at runtime, the GuardedSequenceMemento can be used in place of SequenceMemento. It identifies the caller of the state methods and only allows calls from valid contexts. We call types enforcing such runtime access checks for Guarded Types.

The RangeSequence implementation also supports Java's built in serialization mechanism by implementing the java.io.Serializable interface. It can thus be written to and read from java.io.ObjectOutputStream and java.io.ObjectInputStream objects, respectively, to save and restore its state. Hence, the java.io.Serializable interface can also be considered a representative of the Originator participant, and the target of the OutputObjectStream used, e.g. a file, therefore represents the Memento participant as well.

Gunni Rode / rode.dk

Gunni Rode / rode.dk

Feel free to use and/or modify the Java 6 source code developed for this thesis AT YOUR OWN RISK, but note that the source code comes WITHOUT ANY — and I do mean WITHOUT ANY — form of warranty WHAT SO EVER!

The original thesis and source code are available at rode.dk/thesis.