Jump to content

Шаблон команды

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

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

Использование объектов команд упрощает создание общих компонентов, которым необходимо делегировать, упорядочивать или выполнять вызовы методов в выбранное ими время без необходимости знать класс метода или параметры метода. Использование объекта-вызова позволяет удобно вести учет выполнения команд, а также реализовывать различные режимы для команд, которыми управляет объект-вызов, без необходимости для клиента знать о существовании учета или режимов.

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

Команда [1] Шаблон проектирования — один из двадцати трех известных шаблонов проектирования GoF , которые описывают, как решать повторяющиеся проблемы проектирования для разработки гибкого и многократно используемого объектно-ориентированного программного обеспечения, то есть объектов, которые легче реализовать, изменить, протестировать и повторно использовать.

Использование шаблона проектирования команд может решить следующие проблемы: [2]

  • Следует избегать привязки инициатора запроса к конкретному запросу. То есть следует избегать жестких запросов.
  • Должна быть возможность настроить объект (который вызывает запрос) с помощью запроса.

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

Использование шаблона проектирования команд описывает следующее решение:

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

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

См. также класс UML и диаграмму последовательности ниже.

Структура

[ редактировать ]

Класс UML и диаграмма последовательности

[ редактировать ]
Пример класса UML и диаграммы последовательности для шаблона проектирования «Команда». [3]

На приведенной выше UML классов диаграмме Invoker класс не реализует запрос напрямую.Вместо, Invoker относится к Command интерфейс для выполнения запроса ( command.execute()), что делает Invoker независимо от того, как выполняется запрос. Command1 класс реализует Command интерфейс, выполняя действие над получателем ( receiver1.action1()).

Диаграмма UML последовательности показывает взаимодействие во время выполнения: Invoker вызовы объектов execute() на Command1 объект. Command1 звонки action1() на Receiver1 объект,который выполняет запрос.

Диаграмма классов UML

[ редактировать ]
UML-диаграмма шаблона команды

Использование

[ редактировать ]
Кнопки графического интерфейса и пункты меню
В на Swing и Borland Delphi программировании Action является командным объектом. Помимо возможности выполнить нужную команду, Действие может иметь связанный значок, сочетание клавиш, текст всплывающей подсказки и т. д. Кнопку панели инструментов или компонент пункта меню можно полностью инициализировать, используя только команду действия . Объект
макросов Запись
Если все действия пользователя представлены объектами команд, программа может записывать последовательность действий, просто сохраняя список объектов команд по мере их выполнения. Затем он может «воспроизвести» те же действия, снова последовательно выполняя те же объекты команд. Если в программу встроен механизм сценариев, каждый командный объект может реализовать toScript() , и действия пользователя можно будет легко записать в виде сценариев.
Мобильный код
Используя такие языки, как Java, где код можно передавать в потоковом режиме из одного места в другое через URLClassloaders и Codebases, команды могут обеспечить доставку нового поведения в удаленные места (команда EJB, Master Worker).
Многоуровневая отмена
Если все действия пользователя в программе реализованы как объекты команд, программа может хранить стек последних выполненных команд. Когда пользователь хочет отменить команду, программа просто извлекает самый последний объект команды и выполняет ее. метод отмены() .
сеть
Можно отправлять по сети целые объекты команд для выполнения на других машинах, например действия игрока в компьютерных играх.
Параллельная обработка
Когда команды записываются как задачи для общего ресурса и выполняются многими потоками параллельно (возможно, на удаленных машинах; этот вариант часто называют шаблоном Master/Worker).
Индикаторы выполнения
Предположим, что программа имеет последовательность команд, которые она выполняет по порядку. Если каждый объект команды имеет getEstimatedDuration() , программа может легко оценить общую продолжительность. Он может отображать индикатор выполнения, который значимо отражает, насколько программа близка к выполнению всех задач.
Пулы потоков
Типичный класс пула потоков общего назначения может иметь addTask() , который добавляет рабочий элемент во внутреннюю очередь задач, ожидающих выполнения. Он поддерживает пул потоков, которые выполняют команды из очереди. Элементы в очереди являются объектами команд. Обычно эти объекты реализуют общий интерфейс, например java.lang.Runnable , который позволяет пулу потоков выполнять команду, даже если сам класс пула потоков был написан без каких-либо знаний о конкретных задачах, для которых он будет использоваться.
Транзакционное поведение
Подобно отмене, ядро ​​базы данных или установщик программного обеспечения могут хранить список операций, которые были или будут выполнены. Если один из них выйдет из строя, все остальные можно отменить или отбросить (обычно это называется откатом ). Например, если необходимо обновить две таблицы базы данных, ссылающиеся друг на друга, а второе обновление завершается неудачей, транзакцию можно откатить, чтобы первая таблица не содержала недопустимую ссылку.
Волшебники
Часто мастер представляет несколько страниц конфигурации для одного действия, которое происходит только тогда, когда пользователь нажимает кнопку «Готово» на последней странице. В таких случаях естественным способом отделения кода пользовательского интерфейса от кода приложения является реализация мастера с использованием командного объекта. Объект команды создается при первом запуске мастера. Каждая страница мастера сохраняет изменения графического интерфейса в объекте команды, поэтому объект заполняется по мере продвижения пользователя. «Готово» просто вызывает вызов выполнять() . Таким образом, класс команды будет работать.

Терминология

[ редактировать ]

Терминология, используемая для описания реализаций шаблонов команд, непоследовательна и поэтому может сбивать с толку.Это результат двусмысленности , использования синонимов и реализаций, которые могут скрыть исходный шаблон, выходя далеко за его пределы.

  1. Двусмысленность.
    1. Термин команда неоднозначен. Например, движение вверх, движение вверх может относиться к одной команде (перемещение вверх), которую следует выполнить дважды, или к двум командам, каждая из которых выполняет одно и то же действие (перемещение вверх). Если первая команда добавляется дважды в стек отмены, оба элемента стека относятся к одному и тому же экземпляру команды. Это может быть уместно, когда команду всегда можно отменить одним и тем же способом (например, движение вниз). И в « Банде четырех» , и в приведенном ниже примере Java используется такая интерпретация термина «команда» . С другой стороны, если последние команды добавляются в стек отмены, стек ссылается на два отдельных объекта. Это может быть уместно, когда каждый объект в стеке должен содержать информацию, позволяющую отменить команду. Например, чтобы отменить команду удаления выделения , объект может содержать копию удаленного текста, чтобы его можно было вставить повторно, если удаления выделения необходимо отменить команду . Обратите внимание, что использование отдельного объекта для каждого вызова команды также является примером Схема цепочки ответственности .
    2. Термин «выполнить» также неоднозначен. командного объекта Это может относиться к запуску кода, определенного методом выполнения . Однако в Microsoft Windows Presentation Foundation команда считается выполненной, когда был вызван метод выполнения команды , но это не обязательно означает, что код приложения был запущен. Это происходит только после некоторой дальнейшей обработки событий.
  2. Синонимы и омонимы .
    1. Клиент, Источник, Invoker : нажатие кнопки, кнопки панели инструментов или пункта меню, сочетание клавиш, нажатое пользователем.
    2. Объект команды, объект маршрутизированной команды, объект действия : одноэлементный объект (например, существует только один CopyCommand объект), который знает о сочетаниях клавиш, изображениях кнопок, тексте команды и т. д., связанных с командой. Объект-источник или вызывающий объект вызывает метод выполнения или PerformAction объекта Command или Action. Объект «Команда/Действие» уведомляет соответствующие объекты источника/вызова, когда доступность команды/действия изменилась. Это позволяет кнопкам и пунктам меню становиться неактивными (выделенными серым цветом), когда команда/действие не может быть выполнено/выполнено.
    3. Получатель, целевой объект : объект, который будет скопирован, вставлен, перемещен и т. д. Объект-получатель владеет методом, который вызывается методом выполнения команды . Получатель обычно также является целевым объектом. Например, если объект-получатель является курсором и метод вызывается moveUp, то можно было бы ожидать, что курсор является целью moveUp действие. С другой стороны, если код определяется самим объектом команды, целевой объект будет совершенно другим объектом.
    4. Объект команды, аргументы перенаправленного события, объект события : объект, который передается из источника в объект команды/действия, в целевой объект и в код, который выполняет работу. Каждое нажатие кнопки или сочетание клавиш приводит к созданию нового объекта команды/события. Некоторые реализации добавляют дополнительную информацию к объекту команды/события, поскольку она передается от одного объекта (например, CopyCommand) в другой (например, раздел документа). В других реализациях объекты команд/событий помещаются в другие объекты событий (например, блок внутри большего блока) по мере их перемещения по линии, чтобы избежать конфликтов имен. (См. также схему цепочки ответственности .)
    5. Хэндлер, ExecutedRoutedEventHandler, метод, функция : фактический код, выполняющий копирование, вставку, перемещение и т. д. В некоторых реализациях код обработчика является частью объекта команды/действия. В других реализациях код является частью объекта-получателя/целевого объекта, а в других реализациях код обработчика хранится отдельно от других объектов.
    6. Диспетчер команд, Диспетчер отмены, Планировщик, Очередь, Диспетчер, Вызов : объект, который помещает объекты команд/событий в стек отмены или стек повторов или удерживает объекты команд/событий до тех пор, пока другие объекты не будут готовы к действию с ними, или который направляет объекты команды/события соответствующему объекту получателя/цели или коду обработчика.
  3. Реализации, выходящие далеко за рамки исходного шаблона команд.
    1. Microsoft Windows Presentation Foundation (WPF) представляет маршрутизируемые команды, которые сочетают в себе шаблон команды с обработкой событий. В результате объект команды больше не содержит ни ссылки на целевой объект, ни ссылки на код приложения. командного объекта Вместо этого вызов команды выполнения приводит к так называемому выполненному маршрутизированному событию , которое во время туннелирования или всплытия события может столкнуться с так называемым объектом привязки , который идентифицирует цель и код приложения, который выполняется в этот момент.

Эта реализация C++14 основана на реализации до C++98, описанной в книге.

#include   <iostream>  #include   <memory>  class   Command   {  public  :    // объявляет интерфейс для выполнения операции.    виртуальная   недействительность   выполнения  ()   =   0  ;    виртуальный   ~  Команда  ()   =   по умолчанию  ;  защищено  :    Команда  ()   =   по умолчанию  ;  };  template   <  typename   Receiver  >  class   SimpleCommand   :   public   Command   {   // ConcreteCommand  public  :    typedef   void   (  Receiver  ::*   Action  )();    // определяет привязку между объектом-приемником и действием.    SimpleCommand  (  std  ::  shared_ptr  <Receiver>  receiver_   SimpleCommand  ,   Action   action_  )   :      получатель  (  receiver_.get  )  SimpleCommand  )   действие  (  action_  )   {   }    (  (  const   delete  &  )   =   ;  ,   // правило трех    const   SimpleCommand  &   оператор  =  (  const   SimpleCommand  &  )   =   delete  ;    // реализует выполнение, вызывая соответствующую операцию(и) на приемнике.    virtual   void   выполнить  ()   {      (  приемник  ->*  действие  )();    }  Частное  :    Получатель  *   получатель  ;    действие   Действие  ;  };  class   MyClass   {   // Получатель  public  :    // знает, как выполнять операции, связанные с выполнением запроса. Любой класс может служить получателем.    void   action  ()   {      std  ::  cout   <<   "MyClass::action  \n  "  ;    }  };  int   main  ()   {    // Интеллектуальные указатели предотвращают утечки памяти.    стандартный  ::  shared_ptr <MyClass>   получатель   =   std  ::  make_shared  <MyClass>  ;  )  (    // ...    std  ::  unique_ptr  <  Command  >   команда   =   std  ::  make_unique  <  SimpleCommand  <  MyClass  >   >  (  приемник  ,   &  MyClass  ::  action  );    // ...    команда  ->  выполнить  ();  } 

Вывод программы

МойКласс  ::  действие 

См. также

[ редактировать ]

Первое опубликованное упоминание об использовании класса Command для реализации интерактивных систем, по-видимому, было в статье Генри Либермана 1985 года. [4] Первое опубликованное описание (многоуровневого) механизма отмены-повтора с использованием класса Command с методами выполнения и отмены , а также списка истории, по-видимому, является первым (1988 г.) изданием Бертрана Мейера книги «Объектно-ориентированное программное обеспечение». Строительство , [5] раздел 12.2.

  1. ^ Эрих Гамма; Ричард Хелм; Ральф Джонсон; Джон Влиссидес (1994). Шаблоны проектирования: элементы объектно-ориентированного программного обеспечения многократного использования . Эддисон Уэсли. стр. 233 и далее . ISBN  0-201-63361-2 .
  2. ^ «Шаблон проектирования «Команда» — проблема, решение и применимость» . w3sDesign.com . Архивировано из оригинала 23 сентября 2020 г. Проверено 12 августа 2017 г.
  3. ^ «Шаблон проектирования «Команда» — структура и сотрудничество» . w3sDesign.com . Проверено 12 августа 2017 г. [ мертвая ссылка ]
  4. ^ Либерман, Генри (1985). «Системы меню — это нечто большее, чем просто экран». ACM SIGGRAPH Компьютерная графика . 19 (3): 181–189. дои : 10.1145/325165.325235 .
  5. ^ Мейер, Бертран (1988). Объектно-ориентированное построение программного обеспечения (1-е изд.). Прентис-Холл.
[ редактировать ]
Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: 229fa310904ebffd67d2db570dcb88f4__1711295820
URL1:https://arc.ask3.ru/arc/aa/22/f4/229fa310904ebffd67d2db570dcb88f4.html
Заголовок, (Title) документа по адресу, URL1:
Command pattern - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)