Skip to content

Week 8b - Command Design Pattern

The Command Design Pattern

Classification

  • Behavioral Design Pattern

Pattern Definition

  • Hard Definition: Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.
  • Easy Definition: Implements loose coupling in a request response model.

Representations

Mermaid Graph

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
classDiagram
    ConcreteCommand ..|> Command
    ConcreteCommand --> Receiver
    Invoker --> Command
    Client --> Receiver
    Client --> ConcreteCommand
    class Command{
        <<interface>>
        +execute() : void
        +undo()
    }
    class ConcreteCommand{
        -Receiver receiver
        +ConcreteCommand(Receiver receiver)
        +execute(): void "receiver.action()"
        +undo()
    }
    class Receiver {
        +action()
    }
    class Invoker {
        -Command command
        +Invoker(Command command)
        +setCommand()
    }
    class Client{
        -Receiver r
        -Command concreteCommand
        -Invoker i
    }

UML

Command Pattern

Usage Notes

  • Command is the core of command design pattern that defines the contract for implementation.
  • Receiver implementation is separate from command implementation.
  • Command implementation classes chose the method to invoke on receiver object, for every method in receiver there will be a command implementation. It works as a bridge between receiver and action methods.
  • Invoker class just forward the request from client to the command object.
  • Client is responsible to instantiate appropriate command and receiver implementation and then associate them together.
  • Client is also responsible for instantiating invoker object and associating command object with it and execute the action method.
  • Command design pattern is easily extendible, we can add new action methods in receivers and create new Command implementations without changing the client code.
  • The drawback with Command design pattern is that the code gets huge and confusing with high number of action methods and because of so many associations.

Real World Usages

  • Runnable Interface
  • JavaFX ActionEvent

Java Code Example

Main Take-Aways from the textbook

  • The Command Pattern decouples an object making a request from the one that knows how to perform it.
  • A Command object is at the center of this decoupling and encapsulates a receiver with an action (or set of actions).
  • An invoker makes a request of a Command object by calling its execute() method, which invokes those actions on the receiver.
  • Invokers can be parameterized with Commands, even dynamically at runtime.
  • Commands may support undo by implementing an undo() method that restores the object to its previous state before the execute() method was last called.
  • MacroCommands are a simple extension of the Command Pattern that allow multiple commands to be invoked. Likewise, MacroCommands can easily support undo().
  • In practice, it’s not uncommon for “smart” Command objects to implement the request themselves rather than delegating to a receiver.
  • Commands may also be used to implement logging and transactional systems.

Main OOP Principles of Command Pattern