Использование шаблона стратегии и шаблона команды

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

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

Какие определения определяют, следует ли использовать один шаблон или другой?

Ответ 1

Я включаю таблицу иерархии инкапсуляции нескольких шаблонов дизайна GoF, чтобы помочь объяснить различия между этими двумя шаблонами. Надеюсь, это лучше иллюстрирует то, что каждый инкапсулирует, поэтому мое объяснение имеет больше смысла.

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

design pattern encapsulation hierarchy table

Как видно из таблицы, объект Strategy Pattern скрывает детали реализации алгоритма, поэтому использование другого объекта стратегии будет выполнять те же функции, но другим способом. Каждый объект стратегии может быть оптимизирован для определенного фактора или работать с каким-либо другим параметром; и, используя общий интерфейс, контекст может безопасно работать и с.

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

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

Ответ 2

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

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

Ответ 3

Отвечая на очень старый вопрос. (кто-нибудь видит самые последние ответы вместо большинства проголосовавших?)

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

Ключевое различие заключается в том, чтобы понять, что инкапсулировано. Принцип OO, оба шаблона зависят от, заключается в том, что инкапсулирует то, что меняется.

В случае стратегии меняется то, что алгоритм. Например, один объект стратегии знает, как выводить в файл XML, в то время как другие выходы, скажем, JSON. Различные алгоритмы хранятся (инкапсулируются) в разных классах. Это так просто.

В случае команды зависит от самого запроса. Запрос может исходить от File Menu > Delete или Right Click > Context Menu > Delete или Just Delete Button pressed. Все три случая могут генерировать 3 командных объекта одного типа. Эти объекты команд представляют только 3 запроса для удаления; не алгоритм удаления. Поскольку запросы - это куча объектов, мы могли бы легко управлять ими. Внезапно становится тривиальным обеспечить такие функции, как отмена или повтор.

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

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

Я думаю, что команда помогает нам расширить наше понимание инкапсуляции, в то время как стратегия обеспечивает естественное использование инкапсуляции и полиморфизма.

Ответ 4

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

Возможно, сначала попробуйте StrategyOne, если результаты недостаточно хороши, попробуйте StrategyTwo...

Команды привязаны к различным вещам, которые должны произойти, как TryToWalkAcrossTheRoomCommand. Эта команда будет запущена, когда какой-либо объект должен попытаться пройтись по комнате, но внутри нее она может попробовать StrategyOne и StrategyTwo для попытки пройтись по комнате.

Марк

Ответ 5

Возможно, я ошибаюсь, но я рассматриваю command как функцию для выполнения или реакцию. Должно быть не менее двух игроков: тот, кто просит действия, и тот, кто выполняет действие. GUI является типичным примером для шаблона команды:

  • Все кнопки на панели инструментов приложения связаны с некоторыми действиями.
  • Кнопка является исполнителем в этом случае.
  • Действие - это команда в этом случае.

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

strategy немного отличается: он привязан к некоторой области. Стратегия может определять правило для форматирования даты (в UTC? Locale specific?) (Стратегия форматирования даты) или для вычисления квадрата для геометрической фигуры (стратегия "квадратного калькулятора" ). Стратегии в этом смысле являются объектами мухи, которые берут что-то в качестве входных данных ( "дата", "цифра",...) и принимают какое-то решение на его основе. Возможно, не лучшим, но хорошим примером стратегии является один, связанный с интерфейсом javax.xml.transform.Source: в зависимости от того, является ли переданный объект DOMSource или SAXSource или StreamSource, стратегия (= XSLT-трансформатор в этом случае) будет применять разные правила для его обработки. Реализация может быть простой switch или включать цепочку ответственности.

Но между этими двумя шаблонами есть что-то общее: команды и стратегии инкапсулируют алгоритмы в пределах одной семантической области.

Ответ 6

Команда:

Основные компоненты:

  • Команда объявляет интерфейс для абстрактных команд, таких как execute()
  • Получатель знает, как выполнить определенную команду
  • Invoker содержит ConcreteCommand, который должен быть выполнен
  • Клиент создает ConcreteCommand и назначает Receiver
  • ConcreteCommand определяет привязку между Command и Receiver

Workflow:

Клиент вызывает Invoker = > Invoker вызовы ConcreteCommand = > ConcreteCommand. Получатель, который реализует абстрактный метод Command.

Преимущество. Клиент не влияет на изменения в Command и Receiver. Invoker обеспечивает свободную связь между клиентом и получателем. Вы можете запускать несколько команд с тем же Invoker.

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

Чтобы лучше понять понятия, посмотрите на эту статью JournalDev статью от Pankaj Kumar и dzone article Джеймса Сугрю в дополнение к ссылке Википедии.

Вы можете использовать шаблон Command для

  • Разблокируйте вызывающего и получателя команды

  • Внедрить механизм обратного вызова

  • Внедрить функции отмены и повтора

  • Поддерживать историю команд

java.lang.Thread - одна хорошая реализация шаблона Command. Вы можете рассматривать Thread как invoker и класс, реализующий Runnable as ConcreteCommonad/Receiver и run() как команду.

Вариант командной строки Undo/Redo можно прочитать в статье

Стратегия:

Стратегический шаблон очень прост для понимания. Используйте этот шаблон, если

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

Возьмем пример Система бронирования авиабилетов. Фактор тарифа

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

Основные выходы шаблона Стратегия:

  • Это образец поведения
  • Он основан на делегировании
  • Он изменяет кишки объекта, изменяя поведение метода
  • Он использовал для переключения между семейством алгоритмов
  • Изменяет поведение объекта во время выполнения

Похожие сообщения с примерами кода:

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

Реальный мир Пример шаблона стратегии

Ответ 7

Для меня разница - одно из намерений. Реализации обоих шаблонов довольно похожи, но имеют разные цели:

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

  • Для команды компонент, использующий объект, не знает ни , что команда, ни , как, она это делает - она ​​просто знает, как ее вызывать. Задача вызывающего абонента - просто запустить команду - обработка, выполняемая Командой, не является частью основной работы вызывающего.

В этом разница - действительно ли объект, использующий компонент, действительно знает или заботится о том, что делает компонент? В большинстве случаев это можно определить на основе того, возвращает ли объект шаблона значение его вызывающему. Если invoker заботится о том, что делает объект шаблона, то он, вероятно, захочет, чтобы он что-то возвращал, и это будет Стратегия. Если это не волнует какое-либо возвращаемое значение, это, вероятно, Command (обратите внимание: что-то вроде Java Callable по-прежнему является Command, потому что, хотя оно возвращает значение, вызывающий объект не заботится о значении - он просто передает его обратно к тому, что первоначально было предоставлено Командой).