Design Patterns and Frameworks – Command
Oliver Haase
Description
I Classification: Object-based behavioral pattern
I Purpose: Encapsulate a command as an object. Allows to dynamically configure an invoker with a command object.
Invoker can invoke command without knowing its specifics nor the receiver of the command.
I Also known as: Action, Transaction
“Computer Science is the discipline that believes all problems can be solved with one more layer of indirection.” — Dennis DeBruler.
Motivation & Remarks
I Most widely known application of the command pattern:
event listeners for GUI programming
I Remark: Command pattern is the object-oriented counterpart of function pointers in procedural languages
I Remark II: If the command object contains only one operation, function pointers can be considered more lightweight and thus more appropriate
Remarks
I Remark III: In C#, a function pointer is called a delegate.
Example:
p u b l i c d e l e g a t e b o o l e a n FUNC( o b j e c t x , o b j e c t y ) ; p u b l i c b o o l e a n Compare ( o b j e c t x , o b j e c t y ) { . . . } p u b l i c b o o l e a n c o n t a i n s ( o b j e c t x , o b j e c t [ ] f i e l d ) {
CMP Func myFuncObj = new FUNC( Compare ) ; f o r e a c h ( o b j e c t o b j i n f i e l d ) {
i f ( myFuncObj ( o b j , x ) ) r e t u r n t r u e;
}
r e t u r n f a l s e: }
Motivation
I In Java Swing, when a JButtonis pressed, the button invokes theactionPerformed method of a pre-registered
ActionListener command object.
I The ActionListenerinterface contains only the actionPerformed method.
I an ActionListener command object can be registered using theJButton’s addActionListenermethod.
Sample Structure
Applicability
Use the command pattern if you want to
I dynamically configure an object with an action;
I you want to support →undofunctionality;
I you want to keep a log of the executed actions so they can be redone in case of a crash;
I model a complex transaction;
→ in this case the encapsulation of the transaction in a command object reduces code dependencies.
General Structure
Participants
I Command: declares interface for the command invocation
I ConcreteCommand:
I defines the action to be performed
I defines the receiver of the action
I Client: creates a ConcreteCommand–object and passes the receiver into it.
I Invoker: invokes the command through theCommand interface
I Receiver: knows how to perform the action
Interactions
I Client creates concrete command object and determines the receiver
I Invoker stores the concrete command object
I Invoker executes a request by invoking the command object’s execute operation
I If a command can be undone, the command object stores the receiver’s original state so it can be restored later.
I The concrete command object implements the request by calling operation at the receiver object
Undo and Redo
How to implement chains of undos and redos:
I Provide an additionalundo operation in the Command interface;
I In each ConcreteCommandclass, store the state before execution of the executeoperation; this may include:
I all parameters for the action performed by the receiver
I all state information of the receiver that might change due to the execution of the action (→mementopattern)
I Receiver must allow command object to restore receiver’s original state
I Client stores all executed commands in acommand history
→ depth of command history determines number of possible undo/redo steps
I command objects are copied before insertion into command history
Undo and Redo
How to implement chains of undos and redos:
I Provide an additionalundo operation in the Command interface;
I In each ConcreteCommandclass, store the state before execution of the executeoperation; this may include:
I all parameters for the action performed by the receiver
I all state information of the receiver that might change due to the execution of the action (→mementopattern)
I Receiver must allow command object to restore receiver’s original state
I Client stores all executed commands in acommand history
→ depth of command history determines number of possible
Consequences
I Command pattern decouples the entity that invokes a request (Invoker) from the one that knows how to implement it (Command)
I Command objects can be manipulated (configured) and extended as any other object.
I Command objects can be composed to build macro objects.
For this purpose, the composite pattern can be employed.
I New command objects can easily be created without modifying existing classes.
Related Patterns
I The composite patterncan be used to build macro commands (in which case theMacroCommandclass doesn’t point to a receiver object)
I If a command needs to store the receiver’s state (undo), it can use the →memento pattern
I If a command object needs to be copied before being inserted into the command history, then it behaves like aprototype