Паттерн Стратегия (Strategy) представляет шаблон проектирования, который определяет набор алгоритмов, инкапсулирует каждый из них и обеспечивает их взаимозаменяемость. В зависимости от ситуации мы можем легко заменить один используемый алгоритм другим. При этом замена алгоритма происходит независимо от объекта, который использует данный алгоритм.
Данное определение было взято из интернета, из достаточно хорошего источника, но думаю человеку, который мало знаком с программированием или может быть знаком, но должным образом не углублялся в какие-либо термины будет достаточно трудно понять, то о чем идет речь.
Статься создана не для того, чтобы дать лишь определение и завалить вас непонятными словами, статься создана для полного понимания темы, как новичков , так и тех, кто уже в достаточности знаком с c#
(Под новичком подразумевается, тот кто имеет понимание концепции ООП)
Введение
Давайте разберем данный паттерн на примере UML диаграммы классов:
Унифицированный язык моделирования ( UML ) — это язык моделирования общего назначения в области разработки программного обеспечения, предназначенный для обеспечения стандартного подхода к визуализации проектирования системы. Первоначальным мотивом создания UML было желание стандартизировать различные системы обозначений и методы проектирования программного обеспечения. В UML диаграмма классов является одним из шести типов структурных диаграмм . Диаграммы классов являются основой процесса моделирования объектов и моделируют статическую структуру системы.
Диаграмма классов на унифицированном языке моделирования (UML) — это диаграмма статической структуры, которая описывает структуру системы, показывая ее классы, их атрибуты, операции (или методы) и отношения между объектами. Диаграмма классов — это план системы или подсистемы. Диаграммы классов можно использовать для моделирования объектов, составляющих систему, для демонстрации отношений между объектами и для описания ролей этих объектов и предоставляемых ими услуг.
На Рис.1 мы можем заменить три класса , а также один интерфейс.
- Класс Client - объект так скажем действия в вашем проекте, например персонаж в игре
- Интерфейс IStrategy - описывает абстрактные возможные методы класса Client например атака
- Классы StrategyA и StrategyB - имплементируют интерфейс, и реализуют действия (атаки) например, то как персонаж будет атаковать (скорость выстрела, урон)
Разберем пример игры и персонажа с его атакой
Существуют различные виды вооружения, которые используют параметр атаки: урон. Есть виды оружия. В целом они похожи и отличаются в основном видом урона. Стоит отметить, что мы можем изменить урон, модифицировав оружие. В данном случае вполне можно применить паттерн стратегию:
1. Создадим интерфейс IGun - он опишет все возможные абстрактные методы и параметры(Рис.2)
2. Создадим классы оружия - они будут реализовывать данный интерфейс и устанавливать логику выстрела т.к разные виды окружения производят выстрел по-разному (Рис.3, Рис.4)
3. Создадим класс Hero - это наш персонаж, который имеет имя , вид вооружения и умеет стрелять (Рис.5)
Разбор примера и использование
Описание
Теперь давайте разберем пример, который мы написали выше. В данном случае в качестве IStrategy выступает интерфейс IGun, определяющий метод Shoot(). А реализуют этот интерфейс семейство алгоритмов представлено классами Pistol и MachineGun. И данные алгоритмы использует класс Hero.
Иными словами, у нас есть герой, который имеет имя, а также вид оружия (не важной какой) в целом абстрактно он имеет оружие. Мы не можем достоверно знать чем он вооружен, но может с точностью сказать, что оружие он имеет.
Использование
1. Персонаж - Давайте создадим персонажа, дадим ему имя "Воин" и изначально вооружим его Пулеметом с уроном в 1 единицу и вызовем метод Shoot (Рис.6)
В результате работы данного кода мы увидим следующее
Воин Стреляет автоматом и наносит 1 ед урона
И да действительно мы дали персонажу имя "Воин" и вооружили автоматом с уроном в 1 единицу
2. Перевооружение - Теперь давайте вооружим его пистолетом (Рис.7)
В результате работы данного кода мы увидим следующее
Воин Стреляет автоматом и наносит 1 ед урона
Воин Стреляет пистолетом и наносит 10 ед урона
Все верно, сначала мы дали персонажу автомат, а затем пистолет
Вывод
Когда использовать паттерн?
- Когда есть несколько родственных классов, которые отличаются поведением.
- Когда необходимо обеспечить выбор из нескольких вариантов алгоритмов, которые можно легко менять в зависимости от условий
- Когда необходимо менять поведение объектов на стадии выполнения программы
- Когда класс, применяющий определенную функциональность, ничего не должен знать о ее реализации
В примере приведенном выше, логику у оружия может быть описана тоннами строк кода, но при этом для перевооружения война не потребуется писать большое количество условий.
Паттерн стратегия - это полностью объектно-ориентированный код исключающий процедурный стиль условий
Ссылки
Код примера можно найти здесь -https://github.com/RedMooner/StrategyPatternExample