The Command Pattern is a behavioral design pattern that turns a request into a stand-alone object containing all the information about the request. This lets you parameterize methods with different requests, delay or queue a request’s execution, and support undoable operations.
Structure
- Command – Interface with the
execute()
method. - ConcreteCommand – Implements
Command
and defines a binding between a Receiver and an action. - Receiver – Knows how to perform the operation.
- Invoker – Asks the command to execute the request.
- Client – Creates command objects and sets their receivers.
Example in C++
Implementing a basic remote control (Invoker) to turn a light (Receiver) ON and OFF using Command pattern.
#include <iostream>
#include <memory>
#include <functional>
#include <vector>
// Command Interface
class Command {
public:
virtual void execute() = 0;
virtual ~Command() = default;
};
// Receiver
class Light {
public:
void turnOn() const {
std::cout << "Light is ON\n";
}
void turnOff() const {
std::cout << "Light is OFF\n";
}
};
// ConcreteCommand - TurnOn
class LightOnCommand : public Command {
std::reference_wrapper<Light> light;
public:
explicit LightOnCommand(Light& l) : light(l) {}
void execute() override {
light.get().turnOn();
}
};
// ConcreteCommand - TurnOff
class LightOffCommand : public Command {
std::reference_wrapper<Light> light;
public:
explicit LightOffCommand(Light& l) : light(l) {}
void execute() override {
light.get().turnOff();
}
};
// Invoker
class RemoteControl {
std::unique_ptr<Command> command;
public:
void setCommand(std::unique_ptr<Command> cmd) {
command = std::move(cmd);
}
void pressButton() const {
if (command)
command->execute();
}
};
// Client
int main() {
Light livingRoomLight;
auto lightOn = std::make_unique<LightOnCommand>(livingRoomLight);
auto lightOff = std::make_unique<LightOffCommand>(livingRoomLight);
RemoteControl remote;
remote.setCommand(std::move(lightOn));
remote.pressButton(); //Light is ON
remote.setCommand(std::move(lightOff));
remote.pressButton(); // Light is OFF
return 0;
}
Real-World Use Cases
- GUI buttons triggering actions
- Systems with undo/redo
- Job scheduling systems