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


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

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

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

7 116

7 ответов:

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

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

design pattern encapsulation hierarchy table

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Марк

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

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

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

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

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

команда:

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

  1. команда объявляет интерфейс для абстрактных команд, таких как execute()
  2. приемник знает, как выполнить определенную команду
  3. Invoker держит ConcreteCommand, который должен быть исполнен
  4. клиент создает ConcreteCommand и назначить приемник
  5. ConcreteCommand определяет привязку между команда и приемник

документооборот:

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

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

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

для лучшего понимания концепций, взгляните на этот JournalDev статьи by Панкадж Кумар и dzone статьи by James Sugrue в дополнение к ссылке в Википедии.

можно использовать команда шаблон

  1. отделите вызывающего и приемника команды

  2. практическое руководство механизм

  3. реализовать функцию отмены и повтора

  4. ведение истории команд

java.lang.Thread одна хорошая реализация команда узор. Вы можете лечить Thread как invoker & класс реализации Runnable как ConcreteCommonad / Receiver и run() метод команда.

отменить / повторить версию шаблона команды можно читайте на Теодора Норвелластатьи

стратегия:

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

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

пример тариф системы бронирования авиабилетов компонент

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

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

  1. это поведенческий шаблон
  2. он основан на делегировании
  3. он изменяет кишки объекта путем изменения метода поведение
  4. он используется для переключения между семейством алгоритмов
  5. он изменяет поведение объекта во время выполнения

связанные сообщения с примерами кода:

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

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

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

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

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

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