Command

Turns a request into a stand-alone object that contains all information about the request. This transformation lets you parameterize methods with different requests, delay or queue a request’s execution, and support undoable operations.

classDiagram
    class Invoker {
        -Command command
        +setCommand(Command)
        +executeCommand()
    }
    class Command {
        <<interface>>
        +execute()
        +undo()
    }
    class SimpleCommand {
        -payload
        +execute()
    }
    class ComplexCommand {
        -Receiver receiver
        -params
        +execute()
    }
    class Receiver {
        +doSomething(params)
        +doSomethingElse(params)
    }

    Invoker o-- Command
    Command <|.. SimpleCommand
    Command <|.. ComplexCommand
    ComplexCommand --> Receiver

When to use

Use the Command pattern when you want to parameterize objects with operations, queue operations, schedule their execution, or execute them remotely. Use when you want to implement reversible operations.

Explanation

Problem

Imagine you’re building a text-editor application. You need to create a toolbar with a bunch of buttons for various operations. You created a very neat Button class that can be used for buttons on the toolbar as well as for generic buttons in various dialogs.

While all of these buttons look similar, they’re all supposed to do different things. Where would you put the code for the various click handlers of these buttons? The simplest solution is to create tons of subclasses for each place where the button is used. SaveButton, CopyButton, etc. But then you have to duplicate code if the same action can be triggered from a menu and a shortcut.

Solution

The Command pattern suggests that functionality shouldn’t be inside the UI classes. Instead, the specific action (like Copy, Save) should be extracted into a separate class called a Command. The button just stores a reference to a command object and executes it when clicked.

Real world problem

  1. GUI Buttons: As described above.
  2. Job Queues: Converting tasks into objects (commands) allows serializing them to a DB and processing them later by background workers.
  3. Smart Home: A remote control (Invoker) has buttons. “Turn on Light” is a command sent to the Light (Receiver).

Pros and Cons

Pros Cons
- Single Responsibility Principle: You can decouple classes that invoke operations from classes that perform these operations.
- Open/Closed Principle: You can introduce new commands into the app without breaking existing client code.
- Undo/Redo: You can implement undo/redo.
- Composition: You can assemble a set of simple commands into a complex one.
- Complexity: The code may become more complicated since you’re introducing a whole new layer of classes between senders and receivers.

Comparison

  • Strategy: Command is a single action. Strategy is an algorithm.
  • Chain of Responsibility: Command passes a request to a specific receiver. Chain passes it along a chain.
  • Memento: Memento can be used to save the state of the command for Undo operations.

Code example

Typescript

Php