Почему шаблон команд удобен в объектно-ориентированном дизайне?

Я не понимаю, почему шаблон Command удобен в объектно-ориентированном дизайне.

Вместо использования, например, Команда Switch, которая ссылается на класс Lamp, не могу ли я просто создать Switchable абстрактный класс и вызвать его методы?

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


person aneuryzm    schedule 09.06.2011    source источник


Ответы (8)


Ваш Switchable создает абстракцию между вызывающим и получателем, но они все еще связаны (вызывающему объекту нужна ссылка на получателя). Шаблон Command позволяет вам создать это разъединение. Вызывающий говорит некоторому промежуточному компоненту: «Привет, у меня есть эта команда, которую я хотел бы выполнить», а затем промежуточный элемент может динамически передать этот запрос получателю.

ps ... Я предполагаю, что вы вытащили пример Switch из википедии. Это довольно плохой пример того, почему этот паттерн полезен. Взгляните на лучшие примеры.

person Robert Levy    schedule 09.06.2011
comment
спасибо за пример. Однако я до сих пор не вижу преимущества наличия ссылки на получателя в команде, а не в вызывающей стороне. Другими словами, почему их разделение так полезно? В каких ситуациях полезно? - person aneuryzm; 09.06.2011
comment
Является ли основная причина поддерживать код и сделать вызывающую программу более пригодной для повторного использования? Или есть более практические преимущества? - person aneuryzm; 09.06.2011
comment
@Patrick, сохраняя их отдельно, вы можете менять местами наши получатели, не меняя вызывающего (или наоборот). таким образом, упрощается ремонтопригодность. также существуют сценарии, в которых соединение между вызывающими и получателями не может быть определено до времени выполнения на основе файлов конфигурации, пользовательского ввода или какого-либо источника данных. - person Robert Levy; 09.06.2011
comment
@RobertLevy У меня просто вопрос, зачем нам нужен класс Receiver в этом шаблоне? Разъединить ConcreateCommand и Client, правильно? - person duynt; 11.08.2016

Предположим, вы хотите составить такой список:

  • Включите лампу
  • Установить температуру кондиционера
  • Спектакль "Лунная река"

Действия и получатели разные, поэтому вам нужна абстракция, которая будет отделена от них всех. Шаблон Command также пригодится, когда вы хотите поддерживать отмену / повтор или аналогичные действия.

person kevin cline    schedule 09.06.2011
comment
Хорошо, в контексте отмены / повтора, я понимаю. Но в других ситуациях, почему вы хотите разделить вызывающий и получатель? - person aneuryzm; 09.06.2011
comment
Причина в том, что вы хотите, чтобы код оставался удобным в обслуживании, а вызывающий объект более пригодным для повторного использования? Или есть более практические преимущества? - person aneuryzm; 09.06.2011
comment
+1 за механизм истории и CompositeCommand - две классики. Шаблон Command отделяет акт вызова от деталей вызова. Поскольку со стороны Invoker существует только Command.execute (), do отделено от how. @Patrick, это может помочь подумать о пульте дистанционного управления в примере переключения, используемом здесь, или о официанте, принимающем заказ клиента для обработки поваром. - person earcam; 04.12.2012

Давайте посмотрим на это так: когда клиент хочет, чтобы получатель выполнил какую-то задачу, у клиента есть два варианта:

  1. Позвоните приемнику и скажите ему выполнить задание.
  2. Позвоните третьей стороне, которая знает получателя, и третья сторона передаст сообщение получателю.

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

ИЛИ предположим, что вы потеряли пульт, и вам нужно подойти к телевизору и вручную переключить кнопку.

Это обеспечивает гибкость, так что команда может выполняться не только в синхронном, но и в асинхронном режиме.

person AKS    schedule 14.08.2013

You -> Switch -> Light

Здесь переключатель разделяет вас и свет. Таким образом, становится проще включать / выключать свет с помощью переключателя. это использование (удобство) использования шаблона команд.

Вы - Command Invoker
Switch - Command Manager
Command - Turn On / Off
Light - Фактический исполнитель

Если шаблона команд нет, вам придется вручную поместить свет в держатель, когда это необходимо, и удалить его, когда он не нужен.

person bharanitharan    schedule 08.10.2015

Нет. Вы не можете делать с абстракцией то же, что и команда. Фактически, каждый раз вы можете выполнять работу с выкройкой и все остальное по-другому. Но когда вы меняете Switcher с конкретного на абстрактный, что вы должны сделать это для правильного дизайна, независимо от шаблона команды, вы только отделяете клиента переключателя от его реализации, а не разъединяете переключатель (например, Invoker) от Lamp (например, Receiver). потому что, наконец, у вас должна быть ссылка на Lamp в бетах Switcher, что равносильно ее содержанию в Switcher. Обратите внимание, что Лампа бетонная и вы не можете поменять ее на абстрактную. Поэтому, когда у вас есть бетон, и вы работаете с ним много раз и со многими другими атрибутами, вы должны использовать Command Pattern, чтобы отделить лампу от формы Switcher, переместив зависимость Switcher на Lamp внутри класса Command и завязав Switcher на промежуточный класс, то есть Command. Вдобавок я думаю, что образец из Википедии очень полезен.

person Mohammad Yasin    schedule 25.01.2016

Шаблон команды предлагает структурированный способ связывания действий пользователя с системными командами.

Реализуя шаблон Command, вы можете получить структурированную технику хранения команды пользователя и, таким образом, разрешить такие действия, как отмена / повтор.

Например, реализация шаблона Command для простого текстового редактора (GOF - глава 2) будет выглядеть нравится:

введите здесь описание изображения

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

person Menelaos Kotsollaris    schedule 15.04.2017

Думайте о каждом объекте «команды» как о живом объекте или задаче, которая знает, как выполнять что-то самостоятельно. Ваш invoker - это просто очередь или список, который может

1) удерживайте все эти командные объекты и

2) выполняйте их в том порядке / моде, который вам нравится.

Эта модель такая гибкая с точки зрения хендлера, не правда ли? Вызывающий может буферизовать, расставлять приоритеты или следовать любому алгоритму при выполнении задач.

person user1559625    schedule 04.01.2016

Я считаю, что через Command Pattern несколько вызывающих могут использовать одну и ту же команду. Например, в случае редактора функцию копирования (или алгоритм) необходимо вызывать из команды (ctrl + c) или из меню.

Поэтому, если бы вы не реализовали шаблон команды, алгоритм копирования был бы тесно связан с командой ctrl + c, и вам было бы сложно повторно использовать его для вызова из меню редактора.

Так это выглядит ...

Ctrl + C действие -> CopyCommand -> Copy algo

Команда копирования меню -> CopyCOmmand -> Copy algo

Как видно из вышесказанного, источник команды меняется, но место назначения остается прежним (алгоритм копирования)

person Sandeep Khantwal    schedule 20.04.2019