Skip to content
Behavioral

Command

Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.

Intent

Turn a request into a standalone object that contains all information about the request. This transformation lets you pass requests as method arguments, delay or queue execution, and support undo/redo functionality.

Problem

You need to issue requests to objects without knowing anything about the operation being requested or the receiver of the request. You also want to support undo, redo, transaction logging, or macro recording, but embedding all that logic directly in the caller makes the code complex and tightly coupled.

Solution

Create a Command interface with an execute() method (and optionally undo()). Each concrete command encapsulates a receiver and the parameters needed to perform the action. An Invoker stores and triggers commands without knowing what they do. Because commands are objects, they can be stored in a history stack for undo/redo, serialized for logging, or composed into macros.

Participants

  • Command — declares the interface for executing an operation (and optionally undoing it)
  • ConcreteCommand — binds a receiver to an action; implements execute() by invoking the corresponding method on the receiver
  • Invoker — asks the command to carry out the request; maintains command history for undo/redo
  • Receiver — knows how to perform the operations associated with carrying out a request
  • Client — creates a ConcreteCommand and sets its receiver

Advantages

  • Decouples the object that invokes the operation from the one that knows how to perform it
  • Commands are first-class objects that can be manipulated, composed, and extended
  • Easy to add undo/redo by storing executed commands in a history stack
  • Commands can be assembled into composite (macro) commands
  • Supports deferred execution, queuing, and transaction logging

Disadvantages

  • Increases the number of classes since each action becomes its own command class
  • Can be overkill for simple operations that do not need undo or queueing
  • Undo implementation can be complex if commands have side effects on external systems

Real-World Analogy

Ordering at a restaurant works like the Command pattern. You (Client) tell the waiter (Invoker) what you want. The waiter writes it down on an order slip (Command) and passes it to the kitchen (Receiver). The kitchen does not need to interact with you directly, and the waiter does not need to know how to cook. If you change your mind, the waiter can cross off the item (undo). Orders can also be queued and processed in sequence.

Use Cases

  • Text editor operations — type, delete, bold, with full undo/redo history
  • GUI button actions — each button triggers a command object that can be reassigned
  • Transaction systems — commands represent database operations that can be rolled back
  • Remote control devices — each button maps to a command that controls a different device
  • Job queues and task schedulers — commands are serialized and executed asynchronously
  • Macro recording — a sequence of commands is recorded and replayed later

Code Examples

A text editor with undo support. InsertCommand and DeleteCommand operate on a TextDocument receiver, while the Editor invoker maintains a history stack.