Я включаю таблицу иерархии инкапсуляции нескольких шаблонов проектирования 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 для попытки пройти через комнату.
отметка
источник
Возможно, я ошибаюсь, но я отношусь к команде как к выполняемой функции или как к реакции. Должно быть как минимум два игрока: тот, кто запрашивает действие, и тот, кто выполняет действие. Графический интерфейс является типичным примером для шаблона команды:
Команда обычно ограничена определенной областью или сферой деятельности, но это не обязательно: у вас могут быть команды, которые выставляют счет, запускают ракету или удаляют файл, реализующий один и тот же интерфейс (например, единственный
execute()
метод) в одном приложении. Часто команды самодостаточны, поэтому им ничего не нужно от исполнителя для обработки задачи, которую они намереваются выполнить (вся необходимая информация предоставляется во время создания), иногда команды являются контекстно-зависимыми и должны иметь возможность обнаруживать этот контекст. ( Команда Backspace должна знать положение каретки в тексте, чтобы правильно удалить предыдущий символ; команда Rollback должна обнаружить текущую транзакцию для отката; ...).Стратегия немного отличается: он более привязан к какой - то области. Стратегия может определять правило для форматирования даты (в формате UTC? Зависит от локали?) (Стратегия «форматирования даты») или для вычисления квадрата геометрической фигуры (стратегия «квадратного калькулятора»). В этом смысле стратегии - это легковесные объекты, которые принимают что-то в качестве входных данных («дату», «цифру», ...) и на их основе принимают какое-то решение. Возможно, не лучшим, но хорошим примером стратегии является стратегия, связанная с
javax.xml.transform.Source
интерфейсом: в зависимости от того, является ли переданный объектDOMSource
илиSAXSource
илиStreamSource
стратегия (= преобразователь XSLT в данном случае) будет применять разные правила для его обработки. Реализация может быть простойswitch
или включать шаблон цепочки ответственности .Но на самом деле между этими двумя шаблонами есть что-то общее: команды и стратегии инкапсулируют алгоритмы в одной семантической области.
источник
Команда:
Основные компоненты:
execute()
Процедура:
Клиент вызывает Invoker => Invoker вызывает ConcreteCommand => ConcreteCommand вызывает метод Receiver , который реализует абстрактный метод Command .
Преимущество : на клиента не влияют изменения в Command и Receiver. Invoker обеспечивает слабую связь между клиентом и получателем. Вы можете запускать несколько команд с одним и тем же Invoker.
Команда шаблон позволяет выполнить команду на различных приемниках с помощьюже Invoker . Invoker не знает тип получателя
Для лучшего понимания концепций, взглянуть на эту JournalDev статью по Pankaj Kumar и DZone статьи по Джеймс Sugrue в дополнение к Википедии ссылки.
Вы можете использовать командный шаблон для
Разделите вызывающего и получателя команды
Реализовать механизм обратного вызова
Реализовать функции отмены и повтора
Вести историю команд
java.lang.Thread
- одна хорошая реализация паттерна Command . Вы можете рассматривать Thread как вызывающий объект и класс, реализующий Runnable как ConcreteCommonad / Receiver, аrun()
метод как Command .Версию шаблона команды Undo / Redo можно прочитать в статье Теодора Норвелла.
Стратегия:
Шаблон стратегии очень прост для понимания. Используйте этот шаблон, когда
У вас есть несколько реализаций алгоритма, и реализация алгоритма может меняться во время выполнения в зависимости от конкретных условий .
Рассмотрим пример компонента Fare системы бронирования авиакомпаний.
Авиакомпании хотели бы предлагать разные тарифы в разные периоды времени - в пиковые и непиковые месяцы. Во время непиковых поездок компания хотела бы стимулировать спрос, предлагая привлекательные скидки.
Ключевые выводы паттерна Стратегия :
Связанные сообщения с примерами кода:
Использование шаблона Command Design
Пример шаблона стратегии из реального мира
источник
Для меня разница заключается в намерениях. Реализации обоих шаблонов очень похожи, но имеют разные цели:
Для стратегии компонент, использующий объект, знает, что делает объект (и будет использовать его для выполнения части своей работы), но ему все равно, как он это делает.
Для Команды компонент, использующий объект, не знает ни того, что делает Команда, ни того, как она это делает - он просто знает, как ее вызвать. Задача вызывающего абонента - просто запустить команду - обработка, выполняемая Командой, не является частью основной работы вызывающего.
В этом разница - действительно ли объект, использующий компонент, знает или заботится о том, что делает компонент? В большинстве случаев это можно определить на основе того, возвращает ли объект шаблона значение своему вызывающему. Если вызывающий заботится о том, что делает объект шаблона, он, вероятно, захочет что-то вернуть, и это будет стратегия. Если его не волнует какое-либо возвращаемое значение, это, вероятно, команда (обратите внимание, что-то вроде Java Callable все еще является командой, потому что, хотя оно возвращает значение, вызывающий не заботится о значении - он просто передает его обратно к тому, что изначально предоставило команду).
источник