Команда (шаблон проектирования)

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску
Команда
Command
Тип поведенческий
Назначение для обработки команды в виде объекта
Родственные шаблоны Компоновщик, Хранитель, Прототип, Одиночка
Описан в Design Patterns Да

Команда (англ. Command) — поведенческий шаблон проектирования, используемый при объектно-ориентированном программировании, представляющий действие. Объект команды заключает в себе само действие и его параметры.

Цель[править | править код]

Создание структуры, в которой класс-отправитель и класс-получатель не зависят друг от друга напрямую. Организация обратного вызова к классу, который включает в себя класс-отправитель.

Описание[править | править код]

В объектно-ориентированном программировании шаблон проектирования Команда является поведенческим шаблоном, в котором объект используется для инкапсуляции всей информации, необходимой для выполнения действия или вызова события в более позднее время. Эта информация включает в себя имя метода, объект, который является владельцем метода и значения параметров метода.

Четыре термина всегда связаны с шаблоном Команда: команды (command), приёмник команд (receiver), вызывающий команды (invoker) и клиент (client). Объект Command знает о приёмнике и вызывает метод приёмника. Значения параметров приёмника сохраняются в команде. Вызывающий объект (invoker) знает, как выполнить команду и, возможно, делает учёт и запись выполненных команд. Вызывающий объект (invoker) ничего не знает о конкретной команде, он знает только об интерфейсе. Оба объекта (вызывающий объект и несколько объектов команд) принадлежат объекту клиента (client). Клиент решает, какие команды выполнить и когда. Чтобы выполнить команду он передает объект команды вызывающему объекту (invoker).

Использование командных объектов упрощает построение общих компонентов, которые необходимо делегировать или выполнять вызовы методов в любое время без необходимости знать методы класса или параметров метода. Использование вызывающего объекта (invoker) позволяет вести учёт выполненных команд без необходимости знать клиенту об этой модели учёта (такой учёт может пригодиться, например, для реализации отмены и повтора команд).

Применение[править | править код]

Шаблон Команда может быть полезен в следующих случаях.

Кнопки пользовательского интерфейса и пункты меню

В Swing и Borland Delphi Action (действие) является объектом команды. В дополнение к способности выполнить нужную команду, Action может иметь связанную с ним иконку, сочетание клавиш, текст всплывающей подсказки и так далее. Кнопка на панели инструментов или пункт меню могут быть полностью инициализированы с использованием только объекта Action.

Запись макросов

Если все действия пользователя представлены в виде объектов команды, программа может записать последовательность действий, просто сохраняя список командных объектов в том порядке, в котором они выполняются. Затем она может «воспроизвести» одни и те же действия, выполняя те же объекты команд в той же последовательности.

Многоуровневая отмена операций (Undo)

Если все действия пользователя в программе реализованы в виде командных объектов, программа может сохранить стек последних выполненных команд. Когда пользователь хочет отменить команду, программа просто выталкивает последний объект команды и выполняет его метод undo().

Сети

Можно отправить объекты команд по сети для выполнения на другой машине, например действие игрока в компьютерной игре.

Индикаторы выполнения

Предположим, что программа имеет последовательность команд, которые она выполняет по порядку. Если каждый объект команды имеет метод getEstimatedDuration() (получить оценочную длительность), программа может легко оценить общую продолжительность процесса. Она может показать индикатор выполнения, который отражает, насколько близка программа к завершению всех задач.

Пулы потоков

Типичный класс пула потоков общего назначения может иметь метод addTask(), который добавляет рабочий элемент к внутренней очереди заданий ожидающих своего выполнения. Он поддерживает пул потоков, которые выполняют команды из очереди. Элементы в очереди являются объектами команд. Как правило, эти объекты реализуют общий интерфейс, такой как java.lang.Runnable, что позволяет пулу потоков запустить команды на выполнение, даже если он сам был написан без каких-либо знаний о конкретных задачах, для которых он будет использоваться.

Транзакции

Аналогично операции «отмена» система управления базами данных (СУБД) или установщик программного обеспечения может хранить список операций, которые были или будут выполнены. Если одна из них закончится неудачей, то все остальные могут быть отменены или быть отброшены (обычно называется откат). Например, если две связанные между собой таблицы базы данных должны быть обновлены, а второе обновление терпит неудачу, то система может откатить транзакцию, чтобы первая таблица не содержала недопустимую ссылку.

Мастера

Часто мастер (мастер установки или любой другой) представляет несколько страниц конфигурации для одного действия, которое происходит только тогда, когда пользователь нажимает на кнопку «Готово» на последней странице. В этих случаях, естественный способ отделить код пользовательского интерфейса от кода приложения является реализация мастера с помощью объекта команд. Объект команда создается при первом отображении мастера. Каждая страница мастера сохраняет свои изменения в объекте команды, поэтому объект заполняется по мере перехода пользователя. Кнопка «Готово» просто запускает метод execute() на выполнение.

Примеры[править | править код]

Пример на C++[править | править код]

Пример на Python[править | править код]

Пример на PHP5[править | править код]

Пример на Java[править | править код]

Пример на Swift 5[править | править код]

Пример на Ruby[править | править код]

Ссылки[править | править код]