Behavioral PatternsCommand PatternMedium⏱️ ~2 min

Command Pattern: Structure & Participants

Pattern Structure

«interface»
Command
+ execute(): void
+ undo(): void
ConcreteCommand
- receiver: Receiver
- state: State
+ execute(): void
+ undo(): void
Receiver
+ action(): void
+ getState(): State
Invoker
- command: Command
+ setCommand(c: Command)
+ executeCommand(): void

Participant Roles

Command Interface: Declares execute() and undo() methods that all concrete commands must implement. This is the contract that allows invokers to work with any command without knowing specifics.

ConcreteCommand: Implements the Command interface and holds a reference to the Receiver. It stores any state needed for undo (parameters, previous values) and delegates actual work to the Receiver. The command knows what to do but the Receiver knows how to do it.

Receiver: The object that performs the actual business logic. It could be a Document, TextEditor, or BankAccount. The Receiver has no knowledge of commands and would work fine without the pattern.

Invoker: Triggers command execution without knowing what the command does. A Button, MenuItem, or CommandQueue holds a Command reference and calls execute() when appropriate.

Client: Creates ConcreteCommand objects and sets their Receiver. The client wires everything together but doesn't execute commands directly.

Execution Flow

First, the Client creates a ConcreteCommand and configures it with a Receiver. Second, the Client passes the command to an Invoker. Third, when triggered, the Invoker calls command.execute(). Fourth, the ConcreteCommand calls methods on its Receiver to perform the actual work. For undo, the Invoker calls command.undo(), and the command restores previous state using stored information.

Interview Tip: Clarify that the Receiver is not optional. Commands that contain all logic (no separate Receiver) violate Single Responsibility Principle (SRP). However, for trivial operations like closing a window, a simple command without a complex receiver is appropriate instead of over-engineering.
💡 Key Takeaways
Command interface defines execute() and undo() contract
ConcreteCommand holds Receiver reference and state for undo
Receiver contains actual business logic, independent of pattern
Invoker triggers commands without knowing implementation details
Client creates commands and wires them to receivers and invokers
📌 Examples
1Button (Invoker) executes SaveCommand (Command) on Document (Receiver)
2MenuItem triggers PrintCommand on Printer
3Keyboard shortcut invokes UndoCommand on CommandHistory
← Back to Command Pattern Overview