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

@Pattern(name="Command", scope=Object, purpose=Behavioural, participants={"Command","ConcreteCommand","Client","Invoker","Receiver"})

Package dk.rode.thesis.command

Implementations and examples of the Command design pattern [Gamma95, p.233].


Interface Summary
Command<E> A command represents a possibly undoable operation on a given receiver.

Class Summary
CommandProcessingResult<E> A command processing result represents the result of executing a list commands by a given command processor.
CommandProcessor A command processor can execute and possibly undo a given group of commands.
CompositeCommand<E> A composite command is a command that represents an number of other contained commands, possibly composite as well, thus forming a tree-like structure.
Creator Simple helper class to create a list of commands based on a sequence for the Main.test(Log, Arguments) method.
EvilCommand<E> An evil command is a test command that will always fail during execution and perhaps on undo as well by specifying that it is undoable while in reality it is not.
LogCommand<E> A log command simply logs the operation performed on the receiver object.
Main Command tests.
NextCommand<E> A next command command will invoke next() on its receiving sequence when it is executed.
NullCommand<E> A null command performs no operation on execute or on undo, is always considered undoable, and carries no state.
ResetCommand<E> A reset command command will invoke reset() on its receiving sequence when it is executed.
ReverseCommand<E> A reserve command command will reverse a given sequence when it is executed, if possible.
SequenceCommand<E> A sequence command is a command that manipulates the state of a sequence when it is executed.

Exception Summary
CommandException A command exception may be explicitly raised in case the execution or undoing of a command fails.
EvilCommand.EvilCommandException The exception type thrown during execution and perhaps on undo of the an evil command.

Package dk.rode.thesis.command Description

Implementations and examples of the Command design pattern [Gamma95, p.233].


Here, the Command interface represents the Command participant, and any concrete Command implementation represent the ConcreteCommand participant, for example NextCommand and ReverseCommand.

The Receiver participant is represented by instances of Sequence for all commands that operate on sequences, i.e. sub-classes of SequenceCommand, while it can be any object for LogCommand. NullCommand and EvilCommand are receiver-less.

The CommandProcessor class represents the Invoker participant as well as implement a local command history list for undo operations as described by Gamma et al. [Gamma95, p.238].

The Client participant is represented by the test application, i.e. the Main class, which creates commands and asks the command processor to execute (and possibly undo) them.

Finally, CompositeCommand is a macro command as described by Gamma et al. [Gamma95, p.241].

UML Class Diagram:

Implementation notes:
The CommandProcessor is a variant of the POSA Command Processor pattern suggested by Schmidt et al. [Schmidt00, p.397] that also handles commands spawned by other commands during execution. This enables commands to express business-like semantics that can alter the behaviour at runtime depending on data. The commands to spawn can either be supplied at construction time or could be created on the fly. Here, the ReverseCommand may choose to spawn commands during execution, supplied at construction time, if any.

The default strategy for undoing commands with Sequence objects as receivers is to use the Memento pattern: before execution, a SequenceMemento will be created, if the receiver sequence is an instance of the MemorizableSequence type, which can be then used to reset the original sequence value on undo. To handle non-memorizable sequences, specific command types may naturally employ other means to support undo, as is for example the case with the ResetCommand.

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.