
Команда на Python
Команда — это поведенческий паттерн, позволяющий заворачивать запросы или простые операции в отдельные объекты.
Это позволяет откладывать выполнение команд, выстраивать их в очереди, а также хранить историю и делать отмену.
Сложность:
Популярность:
Применимость: Паттерн можно часто встретить в Python-коде, особенно когда нужно откладывать выполнение команд, выстраивать их в очереди, а также хранить историю и делать отмену.
Признаки применения паттерна: Классы команд построены вокруг одного действия и имеют очень узкий контекст. Объекты команд часто подаются в обработчики событий элементов GUI. Практически любая реализация отмены использует принципа команд.
Концептуальный пример
Этот пример показывает структуру паттерна Команда, а именно — из каких классов он состоит, какие роли эти классы выполняют и как они взаимодействуют друг с другом.
main.py: Пример структуры паттерна
from __future__ import annotations from abc import ABC, abstractmethod class Command(ABC): """ Интерфейс Команды объявляет метод для выполнения команд. """ @abstractmethod def execute(self) -> None: pass class SimpleCommand(Command): """ Некоторые команды способны выполнять простые операции самостоятельно. """ def __init__(self, payload: str) -> None: self._payload = payload def execute(self) -> None: print(f"SimpleCommand: See, I can do simple things like printing" f"({self._payload})") class ComplexCommand(Command): """ Но есть и команды, которые делегируют более сложные операции другим объектам, называемым «получателями». """ def __init__(self, receiver: Receiver, a: str, b: str) -> None: """ Сложные команды могут принимать один или несколько объектов-получателей вместе с любыми данными о контексте через конструктор. """ self._receiver = receiver self._a = a self._b = b def execute(self) -> None: """ Команды могут делегировать выполнение любым методам получателя. """ print("ComplexCommand: Complex stuff should be done by a receiver object", end="") self._receiver.do_something(self._a) self._receiver.do_something_else(self._b) class Receiver: """ Классы Получателей содержат некую важную бизнес-логику. Они умеют выполнять все виды операций, связанных с выполнением запроса. Фактически, любой класс может выступать Получателем. """ def do_something(self, a: str) -> None: print(f"\nReceiver: Working on ({a}.)", end="") def do_something_else(self, b: str) -> None: print(f"\nReceiver: Also working on ({b}.)", end="") class Invoker: """ Отправитель связан с одной или несколькими командами. Он отправляет запрос команде. """ _on_start = None _on_finish = None """ Инициализация команд. """ def set_on_start(self, command: Command): self._on_start = command def set_on_finish(self, command: Command): self._on_finish = command def do_something_important(self) -> None: """ Отправитель не зависит от классов конкретных команд и получателей. Отправитель передаёт запрос получателю косвенно, выполняя команду. """ print("Invoker: Does anybody want something done before I begin?") if isinstance(self._on_start, Command): self._on_start.execute() print("Invoker: ...doing something really important...") print("Invoker: Does anybody want something done after I finish?") if isinstance(self._on_finish, Command): self._on_finish.execute() if __name__ == "__main__": """ Клиентский код может параметризовать отправителя любыми командами. """ invoker = Invoker() invoker.set_on_start(SimpleCommand("Say Hi!")) receiver = Receiver() invoker.set_on_finish(ComplexCommand( receiver, "Send email", "Save report")) invoker.do_something_important()
Output.txt: Результат выполнения
Invoker: Does anybody want something done before I begin? SimpleCommand: See, I can do simple things like printing (Say Hi!) Invoker: ...doing something really important... Invoker: Does anybody want something done after I finish? ComplexCommand: Complex stuff should be done by a receiver object Receiver: Working on (Send email.) Receiver: Also working on (Save report.)