Описание
Архитектурный паттерн Command представляет собой поведенческий шаблон, который превращает запрос в объект, позволяя параметризацию клиентов с различными запросами, очередь запросов и поддержку операций, которые можно отменить. Этот шаблон инкапсулирует запрос как объект, позволяя разделять отправителя и получателя. Команды могут быть параметризованы, что означает, что вы можете создавать различные команды с разными параметрами без изменения вызывающего объекта (отвечающего за инициацию выполнения команды). Он разделяет отправителя (клиент или вызывающий объект) от получателя (объект, выполняющий операцию), обеспечивая гибкость и расширяемость. Паттерн поддерживает операции, которые можно отменить, сохраняя состояние или обратные команды.
Схожие шаблоны и их отличия
- Command и Chain of Responsibility: В Chain of Responsibility обработчики могут быть реализованы как команды. В этом случае можно выполнять множество различных операций над одним и тем же контекстным объектом, представленным запросом. Однако, в Command запрос сам является объектом Command, позволяя выполнять одну и ту же операцию в ряде различных контекстов, связанных в цепочку.
- Command и Memento: Команды могут использоваться вместе с Memento при реализации функции "отменить". В этом случае команды отвечают за выполнение различных операций над целевым объектом, а мemento сохраняют состояние этого объекта непосредственно перед выполнением команды.
- Command и Strategy: Command и Strategy могут выглядеть похожими, поскольку оба позволяют параметризовать объект с некоторым действием. Однако, они имеют совершенно разные намерения. Command позволяет превратить любую операцию в объект, предоставляя возможность отложить выполнение операции, поместить ее в очередь, сохранить историю команд, отправить команды на удаленные сервисы и т.д. С другой стороны, Strategy обычно описывает различные способы выполнения одной и той же вещи, позволяя заменить эти алгоритмы в рамках одного контекстного класса.
Реализация шаблона в общем виде
- Command Interface: Этот интерфейс, подобный набору правил, который должны следовать все классы команд. Он объявляет общий метод execute(), гарантируя, что каждая конкретная команда знает, как выполнить свою конкретную операцию. Он устанавливает стандарт для всех команд, облегчая управление и выполнение разнообразных операций без необходимости знать детали каждой команды.
- Receiver: Объект, который выполняет операцию. Он хранит информацию о конкретном запросе, включая метод, который нужно вызвать, объект, который владеет этим методом, и значения для параметров метода.
- Invoker: Объект, который знает, как выполнить команду, и возможно, выполняет учет о выполнении команды. Invoker не знает ничего о конкретной команде, он знает только о интерфейсе команды.
- Client: Объект, который создает конкретные команды и назначает их Invoker. Клиент решает, какие команды выполнять и в какие моменты.
Пример
Рассмотрим работу паттерна на примере пульта управления конвеерной установкой.
Создадим интерфейс ICommand.
Создадим класс конвеера.
Создадим классы под команды
Далее класс управления конвейером.
Посмотрим применение.
Результат.