Стратегия (шаблон проектирования)

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску
Стратегия
Strategy
Представление структуры шаблона Strategy
Представление структуры шаблона Strategy
Тип поведенческий
Назначение позволяет использовать различные бизнес-правила или алгоритмы в зависимости от контекста.
Применяется в случаях когда в одном и том же месте в зависимости от текущего состояния системы (или её окружения) должны использоваться различные алгоритмы
Плюсы
  • инкапсуляция реализации различных алгоритмов, система становится независимой от возможных изменений бизнес-правил;
  • вызов всех алгоритмов одним стандартным образом;
  • отказ от использования переключателей и/или условных операторов.
Минусы создание дополнительных классов
Родственные шаблоны Мост, Шаблонный метод, Адаптер
Описан в Design Patterns Да

Стратегия (англ. Strategy) — поведенческий шаблон проектирования, предназначенный для определения семейства алгоритмов, инкапсуляции каждого из них и обеспечения их взаимозаменяемости. Это позволяет выбирать алгоритм путём определения соответствующего класса. Шаблон Strategy позволяет менять выбранный алгоритм независимо от объектов-клиентов, которые его используют.

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

[править | править код]

По типу клиента (или по типу обрабатываемых данных) выбрать подходящий алгоритм, который следует применить. Если используется правило, которое не подвержено изменениям, нет необходимости обращаться к шаблону «стратегия».

  • Программа должна обеспечивать различные варианты алгоритма или поведения
  • Нужно изменять поведение каждого экземпляра класса
  • Необходимо изменять поведение объектов на стадии выполнения
  • Введение интерфейса позволяет классам-клиентам ничего не знать о классах, реализующих этот интерфейс и инкапсулирующих в себе конкретные алгоритмы

Способ решения

[править | править код]

Отделение процедуры выбора алгоритма от его реализации. Это позволяет сделать выбор на основании контекста.

  • Класс Strategy определяет, как будут использоваться различные алгоритмы.
  • Конкретные классы ConcreteStrategy реализуют эти различные алгоритмы.
  • Класс Context использует конкретные классы ConcreteStrategy посредством ссылки на конкретный тип абстрактного класса Strategy. Классы Strategy и Context взаимодействуют с целью реализации выбранного алгоритма (в некоторых случаях классу Strategy требуется посылать запросы классу Context). Класс Context пересылает классу Strategy запрос, поступивший от его класса-клиента.
  • Шаблон Strategy определяет семейство алгоритмов.
  • Это позволяет отказаться от использования переключателей и/или условных операторов.
  • Вызов всех алгоритмов должен осуществляться стандартным образом (все они должны иметь одинаковый интерфейс).

Реализация

[править | править код]

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

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

Полезные сведения

[править | править код]
  • и стратегия, и декоратор могут применяться для изменения поведения конкретных классов. Достоинство стратегии в том, что интерфейс кастомизации не совпадает с публичным интерфейсом и может быть куда более удобным, а недостаток в том, что для использования стратегии необходимо изначально проектировать класс с возможностью регистрации стратегий.

Использование

[править | править код]

Архитектура Microsoft WDF основана на этом паттерне. У каждого объекта «драйвер» и «устройство» есть неизменяемая часть, вшитая в систему, в которой регистрируется изменяемая часть (стратегия), написанная в конкретной реализации. Изменяемая часть может быть и вовсе пустой, что даст ничего не делающий драйвер, но при этом способный участвовать в PnP и управлении питанием.

Библиотека ATL содержит в себе набор классов threading model, которые являются стратегиями (различными реализациями Lock/Unlock, которые потом используются основными классами системы). При этом в этих стратегиях используется статический полиморфизм через параметр шаблона, а не динамический полиморфизм через виртуальные методы.

Пример на Java

Пример на C++

Пример на C#

Примеры на D

Пример на Delphi

Примеры на Javascript

Примеры на PHP

Пример на Python 2.7

Пример на Ruby

Источники информации

[править | править код]
  • Э. Гамма, Р. Хелм, Р. Джонсон, Дж. Влиссидес. Приемы объектно-ориентированного проектирования. Паттерны проектирования = Design Patterns: Elements of Reusable Object-Oriented Software. — СПб.: «Питер», 2007. — С. 366. — ISBN 978-5-469-01136-1. (также ISBN 5-272-00355-1)
  • Шаллоуей, Алан, Тротт, Джейм, Р. Шаблоны проектирования. Новый подход к объектно-ориентированному анализу и проектированию: Пер. с англ. —М.: Издательский дом «Вильямс», 2002. —288 с. ISBN 5-8459-0301-7
  • Grand, M. Шаблоны проектирования в Java: Пер. с англ.. — М.: Новое знание, 2004. — С. 559. — ISBN 5-94735-047-5.