Command Pattern
The Command pattern is a behavioral design pattern that turns a request into a stand-alone object that contains all information about the request. This transformation lets you parameterize methods with different requests, delay or queue a request's execution, and support undoable operations.
Intent
Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.
Motivation
Consider a user interface with buttons. Each button performs a specific action. Without the Command pattern, you would typically have each button directly call its associated action method. However, what if you need to:
- Allow users to undo or redo actions?
- Queue requests to be processed later or in a different order?
- Log requests for auditing or debugging?
The Command pattern provides a flexible solution by encapsulating each request as an object. This Command object contains all the necessary information to perform the action, including the receiver of the action and any parameters. This decouples the invoker (e.g., a button) from the receiver (the object that performs the action).
Command Pattern Structure

Note: This is a conceptual diagram. Actual implementation may vary.
Applicability
Use the Command pattern when you want to:
- Parameterize objects by an action to perform.
- Specify, queue, or execute requests at different times.
- Support undoable operations.
- Log requests to perform.
Structure
The Command pattern involves the following participants:
- Command: Declares an interface for executing an operation.
- ConcreteCommand: Implements the Command interface and binds a receiver to an action. It knows how to perform the action.
- Receiver: Knows how to perform the actual work associated with the request. Any class can be a Receiver.
- Invoker: Asks the command to carry out the request. It holds a reference to a Command object.
- Client: Creates a Command object and sets its receiver.
Consequences
- Decoupling: The Invoker is decoupled from the Receiver. The Invoker only knows about the Command interface, not the concrete command or receiver.
- Extensibility: New commands can be added without changing existing Invokers or Receivers.
- Undo/Redo Support: Commands can store their state and be executed in reverse to support undo functionality.
- Queueing and Logging: Command objects can be stored in lists or queues for later execution or logging.
Example (Conceptual C#)
Let's imagine a simple application that can turn lights on and off.
// Receiver
public class Light
{
public void TurnOn()
{
Console.WriteLine("Light is ON");
}
public void TurnOff()
{
Console.WriteLine("Light is OFF");
}
}
// Command Interface
public interface ICommand
{
void Execute();
void Undo(); // For undoable operations
}
// Concrete Command for Turning On
public class LightOnCommand : ICommand
{
private Light _light;
public LightOnCommand(Light light)
{
_light = light;
}
public void Execute()
{
_light.TurnOn();
}
public void Undo()
{
_light.TurnOff(); // To undo turning on, turn it off
}
}
// Concrete Command for Turning Off
public class LightOffCommand : ICommand
{
private Light _light;
public LightOffCommand(Light light)
{
_light = light;
}
public void Execute()
{
_light.TurnOff();
}
public void Undo()
{
_light.TurnOn(); // To undo turning off, turn it on
}
}
// Invoker
public class Switch
{
private ICommand _command;
public void StoreCommand(ICommand command)
{
_command = command;
}
public void Press()
{
if (_command != null)
{
_command.Execute();
}
}
public void PressUndo()
{
if (_command != null)
{
_command.Undo();
}
}
}
// Client
public class Program
{
public static void Main(string[] args)
{
Light livingRoomLight = new Light();
ICommand lightOn = new LightOnCommand(livingRoomLight);
ICommand lightOff = new LightOffCommand(livingRoomLight);
Switch remote = new Switch();
// Turn on the light
remote.StoreCommand(lightOn);
remote.Press(); // Output: Light is ON
// Turn off the light
remote.StoreCommand(lightOff);
remote.Press(); // Output: Light is OFF
// Undo turning off
remote.PressUndo(); // Output: Light is ON
// Undo turning on
remote.StoreCommand(lightOn); // Re-store the on command to undo it
remote.PressUndo(); // Output: Light is OFF
}
}
Related Patterns
- Strategy: Similar in that it parameterizes behavior, but Command focuses on encapsulating a request as an object for invocation, while Strategy focuses on encapsulating algorithms that can be swapped.
- Composite: Command can be combined with Composite to allow complex menu hierarchies or undoable operations composed of multiple steps.