Command pattern
The command pattern turns requests into objects so you can queue, log, and undo operations. Decouple sender from receiver by encapsulating actions.
Introduction
The Command pattern represents a request as an object. The command can carry the receiver and its parameters, expose a uniform execute() operation, and optionally keep the state needed for undo or replay. This separates the code that asks for an action from the code that performs it.
TL;DR / mental model
Think of a command as a stateful job card. The client fills it in, the invoker decides when to run it, and the receiver does the work. Because the job is an object, it can be stored, queued, logged, composed, or undone when the domain supports those operations.
The Problem It Solves
You're building a text editor. The toolbar has buttons for typing, deleting, and formatting. Each button directly calls the corresponding editor method.
Three buttons today, twelve next quarter. Each handler needs its own undo logic, macro awareness, and logging. The toolbar becomes a dumping ground for unrelated concerns. The core issue is that the invoker (toolbar) is coupled to the receiver (editor), making it hard to treat operations as first-class objects.
Here is what changes when you apply the Command pattern.
Structure
Command defines execute() and undo(). Each concrete command wraps one editor operation with enough state to reverse it. TypeCommand stores the inserted text and position so undo() can delete exactly what was typed. MacroCommand composes multiple commands into one (the Composite pattern inside Command). EditorInvoker maintains undo and redo stacks without knowing what the commands actually do.
Participants
- Command: the small interface for executing a request;
undo()is included when reversal is part of the domain. - Concrete command: stores the receiver, parameters, and any execution state needed by one operation.
- Receiver: performs the real work, such as editing the document.
- Invoker: triggers commands and may manage history, scheduling, retries, or queueing.
- Client: chooses and configures the concrete command, then gives it to the invoker.
Implementation
Each command stores a reference to the receiver (TextEditor) and the state needed to reverse the operation. This design is useful when the same operation is invoked from multiple sources (toolbar buttons, keyboard shortcuts, menu items), or when operations need a lifecycle beyond one direct method call.
One command, one operation
Each command class encapsulates exactly one reversible operation. If your command does two things, split it into two commands and wrap them in a MacroCommand.
Continue Reading with Premium
Unlock this article and every other in-depth system design guide on the platform with SDEpedia Premium.
Related Articles
The strategy pattern extracts a family of algorithms behind an interface so the client can swap behaviors at runtime without touching the context class.
The observer pattern decouples event producers from consumers. A subject notifies all registered observers of state changes without knowing who they are or what they do.
The memento pattern captures an object's internal state as an opaque snapshot and restores it later, enabling undo and rollback without breaking encapsulation.