Инкапсулирует запрос в виде объекта, позволяя тем самым параметризовать клиентов типом запроса, устанавливать очередность запросов, протоколировать их и поддерживать отмену выполнения операций.
Назначение
Инкапсулирует запрос как объект, позволяя тем самым задавать параметры клиентов для обработки соответствующих запросов, ставить запросы в очередь или протоколировать их, а так же поддерживать отмену операций.
Применимость
Используйте паттерн команда когда хотите:
- параметризовать объекты выполняемым действием. Команды представляют собой объектно-ориентированную альтернативу функциям обратного вызова;
- определять, ставить в очередь и выполнять запросы в разное время. Время жизни объекта Command необязательно должно зависеть от времени жизни исходного запроса. Если получателя запроса удается реализовать так, чтобы он не зависел от адресного пространства, то объект-команду можно передать другому процессу, который займется его выполнением;
- поддержать отмену операций. Операция execute объекта Command может сохранить состояние, необходимое для отката действий, выполненных командой. В этом случае в интерфейсе класса Command должен быть дополнительный метод unexecute, которая отменяет действия выполненные командой execute. Выполненные команды хранятся в списке истории. Для реализации произвольного числа уровней отмены и повтора команд нужно обходить этот список соответственно в обратном и прямом направлениях.
- поддержать протоколирование изменений, чтобы их можно было выполнить повторно после аварийной остановки системы. Дополнив интерфейс класса Command операциями сохранения и загрузки, вы сможете вести протокол изменений во внешней памяти. Для восстановления после сбоя нужно будет загрузить сохраненные команды с диска и повторно выполнить их с помощью операции execute;
- структурировать систему на основе высокоуровневых операций, построенных из примитивных. Такая структура типична для систем поддерживающих транзакции. Транзакция инкапсулирует набор изменений данных. Паттерн команда позволяет моделировать транзакции. У всех команд есть общий интерфейс, что дает возможность работать одинаково с любыми транзакциями. С помощью этого паттерна можно легко добавлять в систему новые виды транзакций.
Результаты
- команда разрывает связь между объектом, инициирующим операцию, и объектом, имеющим информацию о том, как ее выполнить;
- команды - это самые настоящие объекты. Допускается манипулировать ими и расширять их точно так же, как в случае с любыми другими объектами;
- из простых команд можно собирать составные. В общем случае составные команды описываются паттерном компоновщик;
- добавлять новые команды легко, поскольку никакие существующие классы изменять не нужно.
Структура
Участники
- Command - команда: объявляет интерфейс для выполнения операции;
- ConocreteCommand - конкретная команда: определяет связь между объектом-получателем Receiver и действием, реализует операцию execute путем вызова соответствующих операций объекта Receiver;
- Client - клиент: создает объект класса ConcreteCommand и устанавливает его получателя;
- Invoker - инициатор: обращается к команде для выполнения запроса;
- Receiver - получатель: располагает информацией о способах выполнения операций, необходимых для выполнения запроса. В роли получателя можем выступать любой класс.