В чем разница между шаблоном разработки Стратегии и шаблоном разработки State?
Каковы различия между шаблоном разработки Стратегии и шаблоном разработки State? Я просматривал довольно много статей в Интернете, но не мог ясно различить разницу.
Может кто-нибудь объяснить, пожалуйста, разницу в терминах непрофессионала?
22 ответа
Честно говоря, на практике эти две модели довольно похожи, и определяющая разница между ними, как правило, зависит от того, кого вы спрашиваете. Некоторые популярные варианты:
- Состояния хранят ссылку на объект контекста, который их содержит. Стратегии нет.
- Состояниям разрешено заменять себя (т.е. изменять состояние объекта контекста на что-то другое), а стратегии - нет.
- Стратегии передаются объекту контекста в качестве параметров, а состояния создаются самим объектом контекста.
- Стратегии обрабатывают только одну конкретную задачу, в то время как государства обеспечивают базовую реализацию для всего (или для большинства всего) объекта контекста.
"Классическая" реализация будет соответствовать состоянию или стратегии для каждого элемента в списке, но вы сталкиваетесь с гибридами, которые имеют смеси обоих. Является ли конкретный из них более государственным или стратегическим у, в конечном счете, вопрос субъективный.
- Шаблон " Стратегия" на самом деле подразумевает наличие другой реализации, которая выполняет (в основном) одно и то же, так что одна реализация может заменить другую, как того требует стратегия. Например, у вас могут быть разные алгоритмы сортировки в шаблоне стратегии. Вызывающие объекты не меняются в зависимости от используемой стратегии, но независимо от стратегии цель одна и та же (сортировка коллекции).
- Модель State - это выполнение разных действий в зависимости от состояния, при этом вызывающий абонент освобождается от бремени размещения каждого возможного состояния. Так, например, у вас может быть
getStatus()
метод, который будет возвращать различные состояния в зависимости от состояния объекта, но вызывающий метод не должен кодироваться по-разному для учета каждого потенциального состояния.
Разница заключается лишь в том, что они решают разные проблемы:
- Шаблон состояния имеет дело с тем, что (состояние или тип) объекта (в) - он инкапсулирует поведение, зависящее от состояния, тогда как
- шаблон Стратегия имеет дело с тем, как объект выполняет определенную задачу - он инкапсулирует алгоритм.
Однако конструкции для достижения этих разных целей очень похожи; оба шаблона являются примерами композиции с делегированием.
Несколько замечаний об их преимуществах:
Используя шаблон State, класс хранения состояний (context) освобождается от знания того, что это за состояние или тип, и какие состояния или типы доступны. Это означает, что класс придерживается принципа открытого-закрытого проектирования (OCP): класс закрыт для изменений в существующих состояниях / типах, но состояния / типы открыты для расширений.
При использовании паттерна " Стратегия" класс, использующий алгоритм (контекст), освобождается от знаний о том, как выполнять определенную задачу (- "алгоритм"). Этот случай также создает приверженность OCP; класс закрыт для изменений относительно того, как выполнить эту задачу, но дизайн очень открыт для добавления других алгоритмов для решения этой задачи.
Это, вероятно, также улучшает приверженность контекстного класса принципу единой ответственности (SRP). В дальнейшем алгоритм становится легко доступным для повторного использования другими классами.
Может кто-нибудь объяснить, пожалуйста, с точки зрения непрофессионала?
Шаблоны проектирования на самом деле не являются концепцией "непрофессионала", но я постараюсь сделать это как можно более понятным. Любой шаблон дизайна можно рассматривать в трех измерениях:
- Проблема, которую решает шаблон;
- Статическая структура паттерна (диаграмма классов);
- Динамика паттерна (диаграммы последовательности).
Давайте сравним состояние и стратегию.
Проблема, которую решает шаблон
State используется в одном из двух случаев [GoF book p. 306]:
- Поведение объекта зависит от его состояния, и оно должно изменить свое поведение во время выполнения в зависимости от этого состояния.
- Операции имеют большие составные условные операторы, которые зависят от состояния объекта. Это состояние обычно представлено одной или несколькими перечисляемыми константами. Часто несколько операций будут содержать одну и ту же условную структуру. Шаблон State помещает каждую ветвь условия в отдельный класс. Это позволяет вам трактовать состояние объекта как отдельного объекта, который может отличаться независимо от других объектов.
Если вы хотите убедиться, что у вас действительно есть проблема, решаемая шаблоном State, вы должны иметь возможность моделировать состояния объекта, используя конечный автомат. Вы можете найти пример применения здесь.
Каждый переход состояния является методом в интерфейсе состояния. Это подразумевает, что для дизайна вы должны быть достаточно уверены в переходах состояний, прежде чем применять этот шаблон. В противном случае, если вы добавите или удалите переходы, потребуется изменить интерфейс и все классы, которые его реализуют.
Лично я не нашел эту модель такой полезной. Вы всегда можете реализовать конечные автоматы, используя таблицу поиска (это не OO-способ, но он работает довольно хорошо).
Стратегия используется для следующего [GoF book p. 316]:
- многие связанные классы отличаются только своим поведением. Стратегии предоставляют способ настроить класс с одним из многих поведений.
- вам нужны разные варианты алгоритма. Например, вы можете определить алгоритмы, отражающие различные компромиссы пространства / времени. Стратегии могут использоваться, когда эти варианты реализованы в виде иерархии классов алгоритмов [HO87].
- алгоритм использует данные, о которых клиенты не должны знать. Используйте шаблон "Стратегия", чтобы избежать выявления сложных, специфичных для алгоритма структур данных.
- класс определяет много поведений, и они появляются как несколько условных операторов в своих операциях. Вместо многих условных выражений перенесите соответствующие условные ветви в свой собственный класс Strategy.
Последний случай применения стратегии связан с рефакторингом, известным как " Заменить условный полиморфизмом".
Резюме: государство и стратегия решают самые разные проблемы. Если ваша проблема не может быть смоделирована с помощью конечного автомата, то, скорее всего, шаблон State не подходит. Если ваша проблема не в инкапсуляции вариантов сложного алгоритма, тогда Стратегия не применяется.
Статическая структура рисунка
State имеет следующую структуру классов UML:
Стратегия имеет следующую структуру классов UML:
Резюме: с точки зрения статической структуры эти две модели в основном идентичны. Фактически, инструменты обнаружения шаблонов, такие как этот, считают, что " структура шаблонов [...] идентична, что запрещает их различение автоматическим процессом (например, без ссылки на концептуальную информацию) ".
Однако может быть существенное различие, если ConcreteStates сами решают переходы состояний (см. " Может определить " ассоциации на диаграмме выше). Это приводит к связи между конкретными состояниями. Например (см. Следующий раздел), состояние A определяет переход в состояние B. Если класс Context принимает решение о переходе в следующее конкретное состояние, эти зависимости исчезают.
Динамика картины
Как упоминалось в разделе "Проблема" выше, " Состояние" означает, что поведение изменяется во время выполнения в зависимости от некоторого состояния объекта. Следовательно, применяется понятие перехода состояния, как обсуждалось с отношением конечного автомата. [GoF] упоминает, что переходы могут быть определены либо в подклассах ConcreteState, либо в централизованном расположении (например, в расположении на основе таблицы).
Давайте предположим простой конечный автомат:
Предполагая, что подклассы решают переход состояния (возвращая следующий объект состояния), динамика выглядит примерно так:
Чтобы показать динамику стратегии, полезно заимствовать реальный пример.
Резюме: Каждый шаблон использует полиморфный вызов, чтобы сделать что-то в зависимости от контекста. В паттерне State полиморфный вызов (переход) часто вызывает изменение следующего состояния. В паттерне "Стратегия" полиморфный вызов обычно не меняет контекст (например, оплата кредитной картой один раз не означает, что вы будете платить через PayPal в следующий раз). Опять же, динамика паттерна состояний определяется соответствующим конечным автоматом, что (для меня) необходимо для правильного применения этого паттерна.
Рассмотрим систему IVR (Interactive Voice Response), которая обрабатывает звонки клиентов. Вы можете запрограммировать его на работу с клиентами по:
- Рабочие дни
- каникулы
Чтобы справиться с этой ситуацией, вы можете использовать State State.
- Отпуск: IVR просто отвечает, что "Звонить можно только в рабочие дни с 9 до 17 часов".
- Рабочие дни: он отвечает, связывая клиента с руководителем службы поддержки клиентов.
Этот процесс подключения клиента к руководителю службы поддержки сам может быть реализован с использованием шаблона стратегии, в котором выбираются руководители на основе одного из следующих факторов:
- По-круговой
- Наименее недавно использованный
- Другие приоритетные алгоритмы
Шаблон стратегии определяет, "как" выполнить какое-либо действие, а шаблон состояния - "когда" их выполнять.
Шаблон стратегии включает в себя перемещение реализации алгоритма из класса хостинга и помещение его в отдельный класс. Это означает, что класс хоста не должен обеспечивать реализацию каждого алгоритма, что может привести к нечистому коду.
Алгоритмы сортировки обычно используются в качестве примера, так как все они выполняют одну и ту же функцию (сортировку). Если каждый отличающийся алгоритм сортировки помещен в свой собственный класс, тогда клиент может легко выбрать, какой алгоритм использовать, и шаблон обеспечивает легкий доступ к нему.
Шаблон состояния включает в себя изменение поведения объекта при изменении состояния объекта. Это означает, что класс хоста не обеспечивает реализацию поведения для всех различных состояний, в которых он может находиться. Класс хоста обычно инкапсулирует класс, который обеспечивает функциональность, которая требуется в данном состоянии, и переключается на другой класс когда состояние меняется.
Стратегия представляет объекты, которые "делают" что-то, с одинаковыми начальными и конечными результатами, но внутренне с использованием разных методологий. В этом смысле они аналогичны представлению реализации глагола. Шаблон состояния OTOH использует объекты, которые "являются" чем-то - состоянием операции. Хотя они могут также представлять операции с этими данными, они больше похожи на представление существительного, чем на глагол, и ориентированы на конечные автоматы.
Шаблон стратегии используется, когда у вас есть несколько алгоритмов для конкретной задачи, и клиент решает, какую фактическую реализацию использовать во время выполнения.
Диаграмма UML из статьи вики- стратегии:
Ключевая особенность:
- Это поведенческий паттерн.
- Это основано на делегировании.
- Он изменяет внутренности объекта, изменяя поведение метода.
- Он используется для переключения между семейством алгоритмов.
- Это изменяет поведение объекта во время выполнения.
Обратитесь к этому сообщению для получения дополнительной информации и примеров из реальной жизни:
Пример шаблона стратегии в реальном мире
Шаблон состояния позволяет объекту изменять свое поведение при изменении его внутреннего состояния
UML-диаграмма из статьи-шаблона wiki State:
Если нам нужно изменить поведение объекта в зависимости от его состояния, мы можем иметь переменную состояния в объекте и использовать блок условия if-else для выполнения различных действий в зависимости от состояния. Шаблон состояния используется для обеспечения систематического и потерянного способа достижения этого посредством реализаций контекста и состояния.
Обратитесь к этой статье для более подробной информации.
Основные отличия от статей об источниках и журналах:
- Разница между государством и стратегией заключается во времени связывания. Стратегия является обязательной моделью, тогда как государство более динамично.
- Разница между государством и стратегией заключается в намерении. Со Стратегией выбор алгоритма довольно стабилен. С State, изменение состояния объекта "context" заставляет его выбирать из своей "палитры" объектов Strategy.
- Контекст содержит состояние в качестве переменной экземпляра, и может быть несколько задач, реализация которых может зависеть от состояния, тогда как в стратегии шаблон стратегии передается как аргумент методу, а объект контекста не имеет никакой переменной для его хранения.
Стратегия: стратегия является фиксированной и обычно состоит из нескольких шагов. (Сортировка представляет собой только один шаг и, таким образом, является очень плохим примером, поскольку она слишком примитивна, чтобы понять цель этого шаблона). Ваша "основная" рутина в стратегии вызывает несколько абстрактных методов. Например, "Войти в стратегию комнаты", "main-method" - это goThroughDoor(), который выглядит следующим образом: подхода Door(), if (locked()) openLock(); открытая дверь(); enterRoom(); очередь(); закрой дверь(); if (wasLocked()) lockDoor();
Теперь подклассы этого общего "алгоритма" для перемещения из одной комнаты в другую через возможную запертую дверь могут реализовывать шаги алгоритма.
Другими словами, подклассификация стратегии не меняет основные алгоритмы, а только отдельные шаги.
ЭТО ВЫШЕ - Шаблон Шаблонного Метода. Теперь поместите относящиеся друг к другу шаги (разблокировка / блокировка и открытие / закрытие) в свои собственные объекты реализации и делегируйте им. Например, замок с ключом и замок с кодовой картой - это два вида замков. Делегирование от стратегии до объектов "Шаг". Теперь у вас есть шаблон стратегии.
Государственный паттерн - это нечто совершенно другое.
У вас есть оберточный объект и обернутый объект. Завернутый - это "состояние". Доступ к объекту состояния возможен только через его оболочку. Теперь вы можете изменить обернутый объект в любое время, поэтому оболочка, похоже, меняет свое состояние или даже "класс" или тип.
Например, у вас есть сервис входа в систему. Он принимает имя пользователя и пароль. У него есть только один метод: вход в систему (String userName, String passwdHash). Вместо того, чтобы решать для себя, принят ли вход в систему, он делегирует решение объекту состояния. Этот объект состояния обычно просто проверяет, является ли комбинация пользователь / пароль действительной, и выполняет вход в систему. Но теперь вы можете поменять "Checker" на тот, который позволяет входить только привилегированным пользователям (например, во время maintanace), или на тот, который не позволяет никому входить в систему. Это означает, что "средство проверки" выражает "состояние входа в систему" системы.
Самое главное отличие: когда вы выбрали стратегию, вы придерживаетесь ее, пока не покончили с ней. Это означает, что вы называете его "основным методом", и пока он работает, вы никогда не меняете стратегию. OTOH в ситуации паттерна состояния во время работы вашей системы вы меняете состояние произвольно по своему усмотрению.
На непрофессиональном языке,
в шаблоне Стратегии нет состояний или все они имеют одно и то же состояние. Все они имеют разные способы выполнения задачи, как разные врачи по-разному лечат одну и ту же болезнь одного и того же пациента с одинаковым состоянием.
В паттерне состояний субъективно существуют такие состояния, как текущее состояние пациента (скажем, высокая температура или низкая температура), в зависимости от которого будет определен следующий курс действий (назначение лекарства). И одно состояние может привести к другому состоянию, поэтому существует состояние излагать зависимость (состав технически).
Если мы технически попытаемся понять это, основываясь на сравнении обоих кодов, мы можем потерять субъективность ситуации, потому что оба выглядят очень похожими.
Как Стратегия, так и структура государства имеют одинаковую структуру. Если вы посмотрите на диаграмму классов UML для обоих шаблонов, они выглядят совершенно одинаково, но их намерения совершенно разные. Шаблон проектирования состояния используется для определения и управления состоянием объекта, а шаблон стратегии - для определения набора взаимозаменяемых алгоритмов и позволяет клиенту выбрать один из них. Таким образом, паттерн "Стратегия" является паттерном, управляемым клиентом, в то время как "Объект" может управлять этим состоянием.
Состояние приходит с небольшими зависимостями внутри классов, производных от состояния: как одно состояние знает о других состояниях, следующих за ним. Например, лето наступает после зимы для любого состояния сезона или состояния доставки после состояния депозита для покупок.
С другой стороны, у стратегии нет таких зависимостей. Здесь любой тип состояния может быть инициализирован на основе типа программы / продукта.
Оба шаблона делегируют базовому классу, который имеет несколько производных, но только в шаблоне State эти производные классы содержат ссылку на класс контекста.
Другой способ взглянуть на это состоит в том, что шаблон "Стратегия" является более простой версией шаблона "Состояние"; подшаблон, если хотите. Это действительно зависит от того, хотите ли вы, чтобы производные состояния содержали ссылки на контекст или нет (то есть: хотите ли вы, чтобы они вызывали методы в контексте).
Для получения дополнительной информации: Роберт С. Мартин (и Мика Мартин) ответят на это в своей книге "Гибкие принципы, модели и практики в C#". ( http://www.amazon.com/Agile-Principles-Patterns-Practices-C/dp/0131857258)
Короче говоря, с помощью паттерна стратегии мы можем установить некоторое поведение на лету, а с паттерном состояния мы можем быть уверены, что объект изменит свое поведение внутренне с изменением своего состояния.
Это довольно старый вопрос, но я также искал те же ответы, и это то, что я обнаружил.
Для паттерна State рассмотрим пример кнопки воспроизведения медиального плеера. Когда мы играем, он начинает играть и информирует контекст о том, что он играет. Каждый раз, когда клиент хочет выполнить операцию воспроизведения, он проверяет текущее состояние игрока. Теперь клиент знает, что состояние объекта воспроизводится через объект контекста, поэтому он вызывает метод действий объектов состояния паузы. Часть клиента, осознающая состояние и в каком состоянии ему необходимо выполнить действие, может быть автоматизирована.
https://www.youtube.com/watch?v=e45RMc76884 https://www.tutorialspoint.com/design_pattern/state_pattern.htm
В случае паттерна "Стратегия" расположение диаграммы классов совпадает с паттерном состояния. Клиент приходит к этой договоренности, чтобы сделать некоторую операцию. То есть вместо разных состояний существуют разные алгоритмы, например, различные анализы, которые необходимо выполнить для шаблона. Здесь клиенты сообщают контексту, что он хочет сделать, какой алгоритм (определенный пользователем бизнес-алгоритм), а затем выполняет это.
https://www.tutorialspoint.com/design_pattern/strategy_pattern.htm
Оба реализуют принцип открытого закрытия, поэтому разработчик может добавлять новые состояния в шаблон состояний и новый алгоритм.
Но различие заключается в том, что они используются, то есть шаблон состояния, используемый для выполнения другой логики, основанной на состоянии объекта. А в случае стратегии другая логика.
Как говорится в Википедии о государственном шаблоне:
Шаблон состояния - это шаблон проектирования программного обеспечения, позволяющий объекту изменять свое поведение при изменении его внутреннего состояния. Этот паттерн близок к концепции конечных автоматов.
Давайте поговорим о реальном примере, это рулевое колесо в автомобиле. Руль можно заменить. Мы можем установить руль большего или меньшего размера. Однако это не является правилом, давайте подумаем, что маленькое рулевое колесо составляет больший угол наклона передних колес автомобиля, чем большее рулевое колесо.
Итак, мы можем сделать вывод, что наш автомобиль ведет себя по-разному в зависимости от установленного рулевого инструмента. Например, если мы установим меньшее рулевое колесо, наш автомобиль будет поворачивать налево или направо быстрее.
Таким образом, автомобиль реагирует на такие события, как
TurnLeft()
или же
TurnRight()
. Однако угол поворота автомобильных колес зависит от выбранного в данный момент рулевого колеса. Попробуем кодировать:
public interface ISteeringWheel
{
void TurnLeft();
void Straight();
void TurnRight();
}
public class BigSteeringWheel : ISteeringWheel
{
public void Straight()
{
Console.WriteLine("BigSteeringWheel is straight");
}
public void TurnLeft()
{
Console.WriteLine("BigSteeringWheel is turned left 10
degrees");
}
public void TurnRight()
{
Console.WriteLine("BigSteeringWheel is turned right 10
degrees");
}
}
public class SmallSteeringWheel : ISteeringWheel
{
public void Straight()
{
Console.WriteLine("SmallHandleBar is straight");
}
public void TurnLeft()
{
Console.WriteLine("SmallHandleBar is turned left
20 degrees");
}
public void TurnRight()
{
Console.WriteLine("SmallHandleBar is turned right 20
degrees");
}
}
и
Automobile
класс:
public class Automobile
{
public ISteeringWheel SteeringWheel { get; private set; }
public Automobile()
{
SteeringWheel = new BigSteeringWheel();
}
public void TurnLeft()
{
SteeringWheel.TurnLeft();
}
public void TurnRight()
{
SteeringWheel.TurnRight();
}
public void SetSteeringWheel(ISteeringWheel handleBar)
{
SteeringWheel = handleBar;
}
}
Шаблон стратегии:
Определение из Википедии:
Шаблон стратегии (также известный как шаблон политики) - это шаблон проектирования программного обеспечения, позволяющий выбирать алгоритм во время выполнения. Вместо непосредственной реализации единственного алгоритма код получает инструкции во время выполнения относительно того, какой из семейства алгоритмов использовать.
Обратите внимание на такие слова, как "семейство используемых алгоритмов". Итак, представим, что у нас есть настоящий автомобиль, и когда водитель поворачивает рулевое колесо влево, мы хотим, чтобы наш автомобиль выполнял следующие действия:
- повернуть автомобильные колеса влево на 10 градусов
- включить левый оранжевый сигнал автомобиля
Итак, два вышеуказанных действия можно рассматривать как "семейные алгоритмы для использования". Давайте закодируем этот пример.
Алгоритм рулевого колеса:
public interface ISteeringWheel
{
void TurnLeft();
void Straight();
void TurnRight();
}
public class BigSteeringWheel : ISteeringWheel
{
public void Straight()
{
Console.WriteLine("BigSteeringWheel is straight");
}
public void TurnLeft()
{
Console.WriteLine("BigSteeringWheel is turned left
10 degrees");
}
public void TurnRight()
{
Console.WriteLine("BigSteeringWheel is turned right
10 degrees");
}
}
Алгоритм указателя поворота:
public interface ITurnSignal
{
void TurnOnLeft();
void TurnOnRight();
}
public class OrangeTurnSignal : ITurnSignal
{
public void TurnOnLeft()
{
Console.WriteLine("Left OrangeTurnSignal is turned on");
}
public void TurnOnRight()
{
Console.WriteLine("Right OrangeTurnSignal is turned on");
}
}
И класс автомобиля:
public class Automobile
{
public ISteeringWheel SteeringWheel { get; private set; }
public ITurnSignal TurnSignal { get; private set; }
public Automobile()
{
SteeringWheel = new BigSteeringWheel();
TurnSignal = new OrangeTurnSignal();
}
public void TurnLeft()
{
SteeringWheel.TurnLeft();
TurnSignal.TurnOnLeft();
}
public void TurnRight()
{
SteeringWheel.TurnRight();
TurnSignal.TurnOnRight();
}
}
ЗАКЛЮЧЕНИЕ:
В
State pattern
и
Strategy pattern
очень похожи друг на друга. Однако есть небольшая разница в том, что
State pattern
имеет одно состояние, и все варианты поведения, такие как "TurnLeft" и "TurnRight", инкапсулированы в один класс. С другой стороны,
Strategy pattern
не имеет единственного состояния, но имеет много состояний, таких как "SteeringWheel" и "TurnSignal". Это различное поведение инкапсулируется с использованием различных объектов стратегии, таких как объекты "SteeringWheel" и "TurnSignal". Таким образом, это главное различие между паттерном Состояние и Стратегия.
Кроме того, мы можем думать о
Strategy pattern
как хорошая альтернатива подклассу. Наследование дает нам очень тесную связь между классами, и эта связь между классами определяется во время компиляции. Тем не мение,
Strategy pattern
использует композицию, которая позволяет настраивать поведение во время выполнения путем композиции с другим объектом.
State pattern
также может рассматриваться как альтернатива для замены многих
if — else
заявления в классе.
Оба шаблона используются для изменения поведения объекта,
По замыслу объект шаблона состояния имеет единственное состояние, а поведение объекта основано на реализованном единственном состоянии (классе) и его подклассах.
Напротив, у стратегии нет единого состояния, а поведение объекта определяется реализацией различных объектов стратегии.
Разница обсуждается в http://c2.com/cgi/wiki?StrategyPattern. Я использовал шаблон "Стратегия", позволяющий выбирать различные алгоритмы в общей структуре для анализа данных. Благодаря этому вы можете добавлять алгоритмы без необходимости изменять общие рамки и их логику.
Типичным примером является то, что у вас есть структура для оптимизации функции. Структура устанавливает данные и параметры. Шаблон стратегии позволяет вам выбирать алгоритмы, такие как спуски с помощью шагов, сопряженные градиенты, BFGS и т. Д., Не изменяя структуру.
"Стратегия" - это всего лишь алгоритм, который вы можете изменить в различных обстоятельствах по вашему желанию, и он что-то обрабатывает за вас. Ex. вы можете выбрать, как сжимать файл. zip или rar... в методе.
Но "Состояние" МОЖЕТ изменить все поведение вашего объекта, когда оно изменяется, даже если оно может изменять другие поля... поэтому у него есть ссылка на его владельца. Вы должны заметить, что изменение поля объекта может вообще изменить поведение объекта. Ex. когда вы меняете State0 на State1 в obj, вы меняете целое число на 10.. поэтому, когда мы вызываем obj.f0(), который выполняет некоторые вычисления и использует это целое число, это влияет на результат.
Когда у вас есть проект, который можно разделить на 2 задачи:
задача 1: вы можете использовать один из двух разных алгоритмов для выполнения: alg1, alg2
задача 2: вы можете использовать один из трех различных алгоритмов для выполнения: alg3, alg4, alg5
alg1 и alg2 взаимозаменяемы; alg3, alg4 и alg5 взаимозаменяемы.
Выбор алгоритма для выполнения задачи 1 и задачи 2 зависит от состояний:
состояние 1: вам нужен alg1 в задаче 1 и alg3 в задаче 2
состояние 2: вам нужен alg2 в задаче 1 и alg5 в задаче 2
Вы в контексте можете изменить состояние объекта с состояния 1 на состояние 2. Тогда ваша задача будет выполняться с помощью alg2 и alg5 вместо alg1 и alg3.
Вы можете добавить больше взаимозаменяемых алгоритмов для задачи 1 или задачи 2. Это шаблон стратегии.
У вас может быть больше состояний с разной комбинацией алгоритмов в задаче 1 и задаче 2. Шаблон состояния позволяет вам переключаться из одного состояния в другое и выполнять различные комбинации алгоритмов.
- В шаблоне стратегии при реализации поиска у нас может быть несколько стратегий поиска, например
NaiveStrategy()
,KMPStrategy()
или жеRabinKarp()
Стратегия. Все они независимы, и есть несколько стабильных вариантов. И самое главное, стратегии не могут переходить одна в другую. ТолькоContext
способен менять стратегии. - State Pattern, с другой стороны, основан на концепции
Finite-State
Machines
. Состояния могут переходить одно в другое. Здесь состояния менее устойчивы по сравнению со стратегиями. И одно, каждое конкретное состояние поддерживает ссылку наcontext
и, следовательно, может переходить в другое состояние.
Итак, суть в том, что в стратегии только контекст может задавать стратегию, в то время как в случае шаблона состояний состояния могут выполнять переход в другие состояния. Стратегии не знают друг о друге в Strategy Pattern. В то время как состояния не знают друг о друге в шаблоне состояний и допускают переход, поскольку они поддерживают ссылку на объект контекста.
«Стратегия делает эти объекты полностью независимыми и не подозревающими друг о друге. Однако состояние не ограничивает зависимости между конкретными состояниями, позволяя им изменять состояние контекста по своему желанию».
Шаблон состояния используется для представления объектов, которые могут менять свое поведение в зависимости от своего состояния. Класс контекста в шаблоне состояния может иметь ссылку только на один интерфейс состояния. Это связано с тем, что состояние объекта может быть только одним в каждый момент времени.
Шаблон стратегии используется для представления объектов, которые могут использовать разные алгоритмы для выполнения задачи. Класс контекста в шаблоне стратегии может иметь ссылку на более чем один интерфейс стратегии. Это связано с тем, что объект контекста может использовать разные алгоритмы в зависимости от ситуации.
В этом состоит основное различие между паттернами состояния и стратегии.