The Command pattern turns a request into a standalone object. This allows you to store, queue, or undo the request later. It also separates the object making the request from the one carrying it out.
Sometimes you need to issue a command without knowing how it’s executed. For example, a user interface might need to turn a light on or off, but it shouldn’t need to know the details of how the light works. The Command pattern wraps actions as objects so they can be passed around, delayed, or undone.
Use this pattern if:
Avoid this pattern if:
The pattern defines five roles:
execute()
method.execute()
and defines the specific action.Imagine a restaurant. You (the client) tell the waiter (invoker) what you want. The waiter writes down your order (command) and takes it to the kitchen (receiver). The waiter doesn’t cook, and you don’t need to know how the food is prepared. Each role is clearly defined.
Here’s a basic Python implementation:
from abc import ABC, abstractmethod
# Command interface
class Command(ABC):
@abstractmethod
def execute(self) -> None:
pass
# Receiver
class Light:
def turn_on(self) -> None:
print("Light is ON")
def turn_off(self) -> None:
print("Light is OFF")
# Concrete commands
class TurnOnCommand(Command):
def __init__(self, light: Light) -> None:
self._light = light
def execute(self) -> None:
self._light.turn_on()
class TurnOffCommand(Command):
def __init__(self, light: Light) -> None:
self._light = light
def execute(self) -> None:
self._light.turn_off()
In this example, commands control a Light
object. You could store these commands in a list, run them later, or add undo features.
See a full implementation on GitHub: command.py on GitHub