BehavioralPythonverifiedVerified

Command Pattern in Python

Encapsulates a request as an object, allowing you to parameterize clients, queue or log requests, and support undoable operations.

How to Implement the Command Pattern in Python

1Step 1: Define the Command interface and receiver

from abc import ABC, abstractmethod


class Command(ABC):
    @abstractmethod
    def execute(self) -> None: ...

    @abstractmethod
    def undo(self) -> None: ...


class Counter:
    def __init__(self) -> None:
        self.value = 0

2Step 2: Implement concrete commands with undo support

class IncrementCommand(Command):
    def __init__(self, counter: Counter, amount: int) -> None:
        self._counter = counter
        self._amount = amount

    def execute(self) -> None:
        self._counter.value += self._amount

    def undo(self) -> None:
        self._counter.value -= self._amount


class ResetCommand(Command):
    def __init__(self, counter: Counter) -> None:
        self._counter = counter
        self._previous_value = 0

    def execute(self) -> None:
        self._previous_value = self._counter.value
        self._counter.value = 0

    def undo(self) -> None:
        self._counter.value = self._previous_value

3Step 3: Create a command history for execute and undo

class CommandHistory:
    def __init__(self) -> None:
        self._history: list[Command] = []

    def execute(self, command: Command) -> None:
        command.execute()
        self._history.append(command)

    def undo(self) -> None:
        if self._history:
            command = self._history.pop()
            command.undo()

4Step 4: Execute commands and undo them

counter = Counter()
history = CommandHistory()

history.execute(IncrementCommand(counter, 10))  # value = 10
history.execute(IncrementCommand(counter, 5))   # value = 15
history.execute(ResetCommand(counter))           # value = 0
history.undo()                                   # value = 15
history.undo()                                   # value = 10
print(counter.value)  # 10

Command Pattern Architecture

hourglass_empty

Rendering diagram...

lightbulb

Command Pattern in the Real World

Think of a restaurant order ticket. A waiter (invoker) takes your order and writes it on a slip (command). The slip is handed to the kitchen (receiver) which executes it. The waiter doesn't cook anything—they just carry and deliver orders. Tickets can be queued, cancelled before cooking, or reviewed in an audit log at day's end.