Introduction
Imagine you are building a smart home application.
The application controls various devices:
Lights
Fans
Air Conditioners
Television
Speakers
A beginner might write something like: class RemoteControl {
Initially, this works.
But what happens when new devices are added?
Garage Door
Curtains
Security Camera
Smart Lock
The remote control class keeps growing.
Soon, it becomes difficult to:
Add new commands
Maintain existing code
Support undo operations
Schedule tasks
Store command history
This is where the Command Design Pattern helps.
Instead of directly executing actions, we convert each request into an object.
What is the Command Pattern?
The Command Pattern is a behavioral design pattern that encapsulates a request as an object.
In simple words:
The Command Pattern converts an action into an object.
Instead of directly calling methods, the client creates command objects that represent actions.
These command objects can then be:
Executed
Stored
Queued
Logged
Undone
Replayed
Real World Analogy
Think about ordering food in a restaurant.
There are four participants:
Customer:
"I want a Burger."
Waiter:
Takes the order.
Chef:
Prepares the food.
Kitchen Equipment:
Actually cooks the food.
The waiter doesn't cook.
The customer doesn't enter the kitchen.
The order slip acts like a Command object.
It contains the request and can be passed around without either side knowing implementation details.
Why Do We Need the Command Pattern?
Suppose we are building a smart home remote.
Without the Command Pattern:
This creates several problems.
Problems Without Command Pattern
1. Large Conditional Statements
As devices increase:
if(...)
else if(...)
else if(...)
The code becomes difficult to maintain.
2. Tight Coupling
The remote directly knows every device.
Remote → Light
Remote → Fan
Remote → TV
Adding new devices requires modifying the remote.
3. No Undo Support
Actions execute immediately.
Undo functionality becomes difficult.
4. No Command History
Executed actions cannot be stored easily.
Solution: Command Pattern
The Command Pattern introduces a new layer.
Instead of directly performing actions, we do:
Remote → Command → Device
Now the remote only knows about commands.
Commands know how to interact with devices.
Key Components of Command Pattern
The Command Pattern typically consists of:
1. Command Interface
Defines a common execute operation.
2. Concrete Commands
Actual command implementations.
3. Receiver
The object that performs the real work.
4. Invoker
Triggers command execution.
5. Client
Creates and connects everything.
Structure of Command Pattern
Client
│
▼
Command
▲
│
Concrete Command
│
▼
Receiver
Invoker
│
▼
Command
Example: Smart Home Remote
Let's implement a simple smart home system.
Step 1: Create Receiver
The receiver performs actual work.
Step 2: Create Command Interface
Step 3: Create Concrete Commands
Light ON Command:
Light OFF Command:
Step 4: Create Invoker
Step 5: Client Code
Output
Light is ON
Light is OFF
How the Command Pattern Works
Let's understand the complete flow.
Step 1
The client creates a receiver.
Light light;
Step 2
The client creates commands.
LightOnCommand
LightOffCommand
Step 3
The invoker receives commands.
remote.setCommand(...)
Step 4
The invoker executes commands.
command->execute();
Step 5
The command delegates work to the receiver.
light->turnOn();
Key Idea Behind Command Pattern
The most important idea is:
Encapsulate a request as an object.
Once requests become objects, they can be:
Stored
Queued
Logged
Scheduled
Replayed
Undone
This flexibility is the biggest strength of the pattern.
Implementing Undo Functionality
One of the most famous applications of the Command Pattern is Undo/Redo.
Modify the interface:
Light ON Command:
Now every command knows how to reverse itself.
Command History
Commands can be stored:
Whenever a command executes:
Undo:
This is how many editors implement Undo functionality.
Macro Commands
A Command can also contain multiple commands.
Example:
Movie Mode
Actions:
Turn Off Lights
Turn On TV
Turn On Speakers
Close Curtains
Instead of pressing multiple buttons, one command executes all actions.
Example:
This is called a Macro Command.
Command vs Strategy Pattern
A common interview question.
| Command Pattern | Strategy Pattern |
|---|---|
| Encapsulates requests | Encapsulates algorithms |
| Focuses on actions | Focuses on behavior |
| Supports undo/redo | Supports runtime algorithm switching |
| Commands can be queued | Strategies are usually executed immediately |
| Represents an operation | Represents an approach |
Command vs Observer Pattern
| Command | Observer |
|---|---|
| Executes actions | Sends notifications |
| Action-oriented | Event-oriented |
| Usually one receiver | Multiple observers |
| Explicit execution | Automatic notification |
Advantages of Command Pattern
1. Loose Coupling
The invoker does not know the receiver's details.
2. Easy Extensibility
New commands can be added without modifying existing code.
3. Supports Undo/Redo
One of the biggest benefits.
4. Command History
Commands can be stored and replayed.
5. Task Scheduling
Commands can execute later.
6. Macro Operations
Multiple commands can be grouped.
Disadvantages of Command Pattern
1. Increased Number of Classes
Every action usually requires a command class.
2. Additional Complexity
For very simple systems, the pattern may feel excessive.
3. More Objects
Applications may create many command instances.
Real World Applications
The Command Pattern is heavily used in:
Text editors (Undo/Redo)
IDEs
Smart home systems
Menu systems
Task schedulers
Job queues
Database transaction systems
GUI frameworks
Macro recording software
Remote control systems
Many desktop applications rely heavily on Command Pattern concepts.
Common Beginner Mistakes
1. Putting Business Logic in Invoker
The invoker should only execute commands.
Avoid:
if(...)
inside the invoker.
2. Creating Commands Without Receivers
Commands should delegate actual work to receivers.
3. Ignoring Undo Requirements
If undo functionality is needed later, design commands accordingly.
4. Creating Too Many Tiny Commands
Not every small operation requires a separate command.
Use the pattern when operations represent meaningful actions.
Simple Visualization
Without Command:
Remote
│
├── Light
├── Fan
├── TV
└── AC
The remote directly depends on devices.
With Command:
Remote
│
▼
Command
│
▼
Receiver
The command acts as a bridge between the invoker and the receiver.
Summary
The Command Design Pattern encapsulates requests as objects, allowing operations to be executed, stored, queued, logged, and undone independently of the objects that perform the actual work.
By decoupling the sender from the receiver, the pattern makes systems more flexible, extensible, and maintainable. It is especially useful when applications require features such as undo/redo, command history, task scheduling, or macro operations.
Whenever actions need to be treated as first-class objects, the Command Pattern provides a clean and scalable solution.