Catalog / Behavioral Patterns / Command Pattern
BEHAVIORAL

Command Pattern

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

Intent & Objective

Turn a request into a stand-alone object containing all information about the request. This transformation lets you pass requests as method arguments, delay or queue a request’s execution, and support reversible undo operations.

👥 Real-World Human Analogies & Social Roles
4 Intuitive Scenarios
Restaurant Order Slip Dining Service

"You tell the waiter what you want. They write down a ticket and pin it to the kitchen queue board, encapsulated to be executed by the cooks later."

Military Field Orders Command & Control

"A general issues a sealed command envelope to be delivered, scheduled, and executed at a specific operational hour."

Smart Voice Assistant Smart Home Automation

"You give a command ('turn off bedroom lights'); the assistant encapsulates it as an action payload and executes it."

Git Commits Developer Daily Life

"Each commit encapsulates a specific change request that can be queued, reviewed, and executed later via a merge or cherry-pick."

The Problem

Directly hardcoding UI buttons to business actions: having `SaveButton` invoke `Document.save()`, `PrintButton` invoke `Printer.print()`. The GUI becomes tightly coupled to backend services, making undo/redo, command macros, and queuing impossible.

The Solution

Separate GUI controls from business actions by introducing Command objects with an `execute()` and `undo()` method. Invokers simply trigger `command.execute()`.

Key Participants & Architectural Roles

Command Interface
Declares an execution interface (typically `execute()` and `undo()`)
Concrete Commands
Implements request by calling the corresponding operations on the Receiver
Receiver
Contains the actual business logic to perform the operation
Invoker
Initiates requests by calling `execute()` on a command

Code Samples (Traditional OOP vs Functional Programming)

Available in C++, Python, and Java

Paradigm Contrast: Traditional OOP vs Functional / Data-Oriented

In OOP, Command is an object containing `execute()` and `undo()`. In Functional Programming, a Command is a closure, thunk, or IO action: a zero-argument function `() -> Result` packaged with its captured parameters.

Advantages

  • ✓ Single Responsibility Principle: decouples classes that invoke operations from classes that perform them
  • ✓ Open/Closed Principle: introduces new commands without breaking existing client code
  • ✓ Enables undo/redo history stacks, macros, and job queuing

Trade-offs

  • ✗ Code may become more complicated since you are introducing a whole new layer between senders and receivers

When to Apply

  • → When you want to parameterize UI elements with operations
  • → When you want to queue operations, schedule their execution, or execute them remotely
  • → When you need to implement reversible operations (Undo/Redo)

When to Avoid

  • ! For direct synchronous method calls that will never need queuing, logging, or undo