Стратегия определяет семейство алгоритмов, инкапсулирует каждый из них и обеспечивает их взаимозаменяемость. Он позволяет модифицировать алгоритмы независимо от их использования на стороне клиента.
-
Когда вам нужно использовать разные вариации какого-то алгоритма внутри одного объекта.
- Стратегия позволяет варьировать поведение объекта во время выполнение программы, подставляя в него различные объекты-поведения (например, отличающиеся балансом скорости и потребления ресурсов).
-
Когда у вас есть множество похожих классов, отличающихся только некоторым поведением.
- Стратегия позволяет вынести отличающееся поведение в отдельную иерархию классов и свести первоначальные классы к одному, сделав его поведение настраиваемым.
-
Когда вы не хотите обнажать детали реализации алгоритмов для других классов.
- Стратегия позволяет изолировать код, данные и зависимости алгоритмов от других объектов, скрыв из внутри собственных классов.
-
Когда различные вариации алгоритмов реализованы в виде развесистого условного оператора. Каждая ветка такого оператора представляет вариацию алгоритма.
- Стратегия помещает каждую лапу такого оператора в отдельный класс-стратегию. Затем контекст получает определённый объект-стратегию от клиента и делегирует ему работу. Если вдруг понадобится сменить алгоритм, в контекст можно подать другую стратегию.
-
Определите алгоритм, который подвержен частым изменениям. Также подойдёт алгоритм, имеющий несколько вариаций, которые выбираются во время выполнения программы.
-
Создайте интерфейс стратегий, описывающий этот алгоритм. Он должен быть общим для всех вариантов алгоритма.
-
Поместите вариации алгоритма в собственные классы, которые реализуют этот интерфейс.
-
В классе контекста создайте поле для хранения ссылки на текущий объект-стратегию, а также метод для её изменения. Убедитесь в том, что контекст работает с этим объектом только через общий интерфейс стратегий.
-
Клиенты контекста должны подавать в контекст соответствующий объект-стратегию, когда хотят, чтобы тот вёл себя определённым образом.
+ | - |
---|---|
Горячая замена алгоритмов на лету. | Усложняет программу за счёт дополнительных классов. |
Изолирует код и данные алгоритмов от остальных классов. | Клиент должен знать, в чём разница между стратегиями, чтобы выбрать подходящую. |
Уход от наследования к делегированию. | |
Реализует принцип открытости/закрытости. |
-
Мост, Стратегия и Состояние (а также слегка и Адаптер) имеют схожие структуры классов - все они построены на принципе «композиции», то есть делегирования работы другим объектам. Тем не менее, они отличаются тем, что решают разные проблемы. Помните, что паттерны - это не только рецепт построения кода определённым образом, но и описание проблем, которые привели к данному решению.
-
Команда и Стратегия похожи по духу, но отличаются масштабом и применением:
-
Команду используют, чтобы превратить любые разнородные действия в объекты. Параметры операции превращаются в поля объекта. Этот объект теперь можно логировать, хранить в истории для отмены, передавать во внешние сервисы и так далее.
-
С другой стороны, Стратегия описывает разные способы сделать одно и то же действие, позволяя взаимозаменять эти способы в каком-то объекте контекста.
-
-
Стратегия меняет поведение объекта «изнутри», а Декоратор изменяет его «снаружи».
-
Шаблонный метод использует наследование, чтобы расширять части алгоритма. Стратегия использует делегирование, чтобы изменять алгоритм. Шаблонный метод работает на уровне классов. Стратегия позволяет менять логику отдельных объектов.
-
Состояние можно рассматривать как надстройку над Стратегией. Оба паттерна используют композицию, чтобы менять поведение основного объекта, делегируя работу вложенным объектам-помощникам. Однако в Стратегии эти объекты не знают друг о друге и никак не связаны. В Состоянии сами конкретные состояния могут переключать контекст.