В чем разница между шаблоном разработки Стратегии и шаблоном разработки State? - PullRequest
198 голосов
/ 01 ноября 2009

В чем различия между шаблоном разработки Стратегии и шаблоном разработки State? Я просматривал довольно много статей в Интернете, но не мог ясно различить разницу.

Может кто-нибудь объяснить разницу в выражениях непрофессионала?

Ответы [ 17 ]

123 голосов
/ 13 октября 2012

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

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

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

91 голосов
/ 01 ноября 2009
  • Шаблон Стратегия на самом деле подразумевает наличие другого реализация, которая выполняет (в основном) то же самое, так что одна реализация может заменить другую, как того требует стратегия. Например, у вас могут быть разные алгоритмы сортировки в шаблон стратегии. Вызывающие объекты на объект не меняются в зависимости от какая стратегия используется, но независимо от стратегии цель то же самое (сортировка коллекции).
  • Шаблон State предназначен для выполнения различных действий на основе состояние, оставляя абонента освобожденным от бремени приспосабливая каждое возможное состояние. Так, например, у вас может быть getStatus() метод, который будет возвращать различные статусы на основе состояние объекта, но вызывающий метод не должен быть кодируется по-разному для учета каждого потенциального состояния.
79 голосов
/ 16 июля 2012

Разница просто в том, что они решают разные задачи:

  • Шаблон State имеет дело с чем (состояние или тип) является объект (в) - он инкапсулирует поведение, зависящее от состояния, тогда как
  • шаблон Strategy описывает , как объект выполняет определенную задачу - он инкапсулирует алгоритм.

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


Некоторые замечания об их преимуществах:

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

При использовании шаблона Strategy класс использования алгоритма (контекст) освобождается от знания , как выполнять определенную задачу (- «алгоритм»). Этот случай также создает приверженность OCP; класс закрыт для изменений относительно того, как выполнить эту задачу, но дизайн очень открыт для добавления других алгоритмов для решения этой задачи.
Это, вероятно, также улучшает приверженность контекстного класса принципу единой ответственности (SRP). В дальнейшем алгоритм становится легко доступным для повторного использования другими классами.

37 голосов
/ 24 мая 2015

Кто-нибудь может объяснить, пожалуйста, в терминах непрофессионала?

Шаблоны проектирования на самом деле не являются "непрофессиональными" понятиями, но я постараюсь сделать их как можно более понятными. Любой шаблон дизайна можно рассматривать в трех измерениях:

  1. Проблема, которую решает шаблон;
  2. Статическая структура шаблона (диаграмма классов);
  3. Динамика паттерна (диаграммы последовательности).

Давайте сравним состояние и стратегию.

Проблема, которую решает шаблон

State используется в одном из двух случаев [GoF book p. 306]

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

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

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

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

Стратегия используется для следующих [GoF book p. 316]

  • многие связанные классы отличаются только своим поведением. Стратегии предоставляют способ настроить класс с одним из многих вариантов поведения.
  • вам нужны разные варианты алгоритма. Например, вы можете определить алгоритмы, отражающие различные компромиссы пространства / времени. Стратегии могут использоваться, когда эти варианты реализованы в виде иерархии классов алгоритмов [HO87].
  • алгоритм использует данные, о которых клиенты не должны знать. Используйте шаблон «Стратегия», чтобы избежать выявления сложных, специфичных для алгоритма структур данных.
  • класс определяет много поведений, и они появляются как несколько условных операторов в своих операциях. Вместо многих условных выражений переместите соответствующие условные ветви в свой собственный класс Стратегии.

Последний случай применения Стратегии связан с рефакторингом, известным как Замените условный полиморфизм .

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

Статическая структура рисунка

Состояние имеет следующую структуру классов UML:

PlantUML class diagram of State Pattern

Стратегия имеет следующую структуру классов UML:

PlantUML class diagram of Strategy Pattern

Резюме: с точки зрения статической структуры, эти две модели в основном идентичны. На самом деле, инструменты обнаружения шаблонов, такие как , этот считают, что " структура [...] шаблоны идентичны, запрещая их различение автоматическим процессом (например, без ссылки к концептуальной информации)."

Однако может быть существенное отличие, если ConcreteStates решат сами переходы между состояниями (см. « может определять » ассоциации на диаграмме выше). Это приводит к связи между конкретными состояниями. Например (см. Следующий раздел), состояние A определяет переход в состояние B. Если класс Context принимает решение о переходе в следующее конкретное состояние, эти зависимости исчезают.

Динамика выкройки

Как упоминалось выше в разделе «Проблема», State подразумевает, что поведение изменяется во время выполнения в зависимости от некоторого состояния объекта. Следовательно, применяется понятие состояния переходного , как обсуждалось с отношением конечного автомата . [GoF] упоминает, что переходы могут быть определены либо в подклассах ConcreteState, либо в централизованном расположении (например, в расположении на основе таблицы).

Давайте предположим простой конечный автомат:

PlantUML state transition diagram with two states and one transition

Предполагая, что подклассы решают переход состояния (возвращая следующий объект состояния), динамика выглядит примерно так:

PlantUML sequence diagram for state transitions

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

PlantUML sequence diagram for strategy transitions

Сводка : Каждый шаблон использует полиморфный вызов, чтобы сделать что-то в зависимости от контекста. В паттерне State полиморфный вызов (переход) часто вызывает изменение следующего состояния . В паттерне Стратегия полиморфный вызов обычно не меняет контекст (например, оплата кредитной картой один раз не означает, что вы будете платить PayPal в следующий раз). Опять же, динамика паттерна состояний определяется соответствующим ему конечным автоматом , , который (для меня) необходим для правильного применения этого паттерна.

25 голосов
/ 02 ноября 2009

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

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

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

13 голосов
/ 17 апреля 2013

Рассмотрим систему IVR (Interactive Voice Response), обрабатывающую звонки клиентов. Вы можете запрограммировать его на работу с клиентами по:

  • Рабочие дни
  • Праздники

Чтобы справиться с этой ситуацией, вы можете использовать State Pattern .

  • Праздник : IVR просто отвечает, что « Звонки можно принимать только в рабочие дни с 9:00 до 17:00 ».
  • Рабочие дни : он отвечает, подключая клиента к руководителю службы поддержки клиентов.

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

  • Круглый Робин
  • Наименее недавно использованные
  • Другие алгоритмы, основанные на приоритетах

Шаблон стратегии выбирает '1048 *, как ' выполнить какое-либо действие, а шаблон состояния выбирает '1050 *, когда ' выполняет их.

13 голосов
/ 01 ноября 2009

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

11 голосов
/ 01 июня 2011

Стратегия: стратегия фиксированная и обычно состоит из нескольких шагов. (Сортировка представляет собой только один шаг и, таким образом, является очень плохим примером, поскольку она слишком примитивна, чтобы понять цель этого шаблона). Ваша «основная» рутина в стратегии вызывает несколько абстрактных методов. Например. «Стратегия входа в комнату», «main-method» - это goThroughDoor (), который выглядит следующим образом: подхода Door (), if (locked ()) openLock (); открытая дверь(); enterRoom (); очередь(); закрой дверь(); if (wasLocked ()) lockDoor ();

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

Другими словами, подклассификация стратегии не меняет основные алгоритмы, только отдельные шаги.

ЭТО ВЫШЕ - Шаблон Шаблонного Метода. Теперь поместите относящиеся друг к другу шаги (разблокировка / блокировка и открытие / закрытие) в свои собственные объекты реализации и делегируйте им. Например. замок с ключом и замок с кодовой картой - это два вида замков. Делегирование от стратегии до объектов «Step». Теперь у вас есть шаблон стратегии.

Шаблон состояний - это нечто совершенно другое.

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

например. у вас есть сервис входа в систему. Он принимает имя пользователя и пароль. У него есть только один метод: вход в систему (String userName, String passwdHash). Вместо того, чтобы решать для себя, принят ли вход в систему или нет, он делегирует решение объекту состояния. Этот объект состояния обычно просто проверяет, является ли комбинация пользователь / пароль действительной, и выполняет вход в систему. Но теперь вы можете обменять «Checker» на тот, который позволяет входить только привилегированным пользователям (например, во время maintanace), или на тот, который не позволяет никому входить в систему. Это означает, что «средство проверки» выражает «состояние входа в систему» ​​системы.

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

8 голосов
/ 25 мая 2016
Шаблон

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

UML-диаграмма из вики Статья с описанием стратегии:

enter image description here

Основные характеристики:

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

См. Этот пост для получения дополнительной информации и примеров из реального мира:

Пример шаблона стратегии в реальном мире

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

UML-диаграмма из вики Состояние шаблона статьи:

enter image description here

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

Подробнее об этом см. В статье journaldev .

Ключевые отличия от sourcemaking и journaldev статей:

  1. Разница между State и Strategy заключается во времени привязки. Стратегия представляет собой модель привязки один раз, тогда как State более динамичен .
  2. Разница между State и Strategy находится в намерении. При использовании стратегии выбор алгоритма достаточно стабилен . С State, изменение состояния объекта «context» заставляет его выбирать из своей «палитры» объектов Strategy .
  3. Контекст содержит состояние в качестве переменной экземпляра, и может быть несколько задач, реализация которых может зависеть от состояния , тогда как в стратегии схеме стратегии * В качестве аргумента метода передается 1099 *, а объект context не имеет переменной для его хранения.
5 голосов
/ 09 октября 2015

На непрофессиональном языке,

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

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

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

...