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

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

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

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

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

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

![]()

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

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

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



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

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

Главное отличие заключается в том, чтобы понятькакие инкапсулирован. Принцип ОО, от которого зависят обе модели:Инкапсулировать то, что меняется.

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

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

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

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

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



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

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

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

отметка



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

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



 но имеют разные цели:

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

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

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



**Команда:**

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

**команда** объявляет интерфейс для абстрактных команд, таких как`execute()`**Получатель** знает, как выполнить определенную команду**Чешуи** держитConcreteCommand, который должен быть выполнен**клиент** создаетConcreteCommand и назначитьПолучатель**ConcreteCommand** определяет связь междукоманда а такжеПолучательПроцедура:

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

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

**команда** Шаблон позволяет выполнить команду на разныхПриемники используя тот жеЧешуи, Invoker не знает типПолучатель

Для лучшего понимания концепций, посмотрите на этот JournalDev[статья](http://www.journaldev.com/1624/command-design-pattern-in-java-example-tutorial) отПанкадж Кумар и dzone[статья](https://dzone.com/articles/design-patterns-command) отДжеймс Сагру в дополнение к ссылке в Википедии.

Ты можешь использовать**команда** шаблон для

Разъедините призывателя и получателя команды

Реализовать механизм обратного вызова

Реализация функций отмены и повтора

Вести историю команд

`java.lang.Thread` одна хорошая реализациякоманда шаблон. Вы можете лечитьНить как вызывающий и реализующий классRunnable какConcreteCommonad / приемник а также`run()` метод каккоманда.

Отменить / повторить версию шаблона команды можно прочитать наТеодор Норвеллс [статья](https://sourcephile.blogspot.in/2011/04/how-to-do-undo-and-redo.html)

**Стратегия:**

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

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

Возьмите пример**Тарифный компонент системы бронирования авиабилетов**

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

Ключевые выносы**стратегия** шаблон:

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

[Использование шаблона Command Design](https://stackoverflow.com/questions/2015549/using-command-design-pattern/34789979#34789979)

[Пример шаблона стратегии в реальном мире](https://stackoverflow.com/questions/370258/real-world-example-of-the-strategy-pattern/35180265#35180265)



Я могу ошибаться, на мой взгляд, но я отношусь к[команда](https://en.wikipedia.org/wiki/Command_pattern) как функция для выполнения или реакция. Должно быть как минимум два игрока: тот, кто запрашивает действие, и тот, кто выполняет действие. GUI является типичным примером для шаблона команды:

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

[стратегия](https://en.wikipedia.org/wiki/Strategy_pattern) немного отличается: он более привязан к некоторой области. Стратегия может определять правило для форматирования даты (в формате UTC «специфично для локали») (стратегия «средство форматирования даты») или для вычисления квадрата для геометрической фигуры (стратегия «квадратный калькулятор»). В этом смысле стратегии - это легковесные объекты, которые принимают что-то в качестве входных данных («дата», «цифра», ...) и принимают решение на его основе. Возможно, не самый лучший, но хороший пример стратегии связан с`javax.xml.transform.Source` интерфейс: в зависимости от того, является ли переданный объект`DOMSource` или же`SAXSource` или же`StreamSource` стратегия (= преобразователь XSLT в этом случае) будет применять различные правила для ее обработки. Реализация может быть простой`switch` или привлекать[Цепочка ответственности](https://en.wikipedia.org/wiki/Chain_of_responsibility_pattern).

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