Паттерн Стратегия

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

Паттерн Стратегия

Реализация: допустим, нам необходимо написать программу для только что открывшегося автозавода. Заказчик пока собирается выпускать только одну модель машин и необходима программа, для хранения характеристик этой модели. Пусть это будет переднеприводный седан. Создадим два класса один абстрактный – Car с одним методом — void drive(), второй класс – AudiA3, который описывает единственную модель автомобиля нашего автогиганта.

В результате выполнения данного кода получим:

All cars can drive!

Продажи нового автомобиля бьют все рекорды и наш автоконцерн решает наладить выпуск новой модели – полноприводного седана. Что же, придется изменят нашу программу, самый простой и очевидный вариант: сделать метод void drive() абстрактным и реализовать его в классах конкретных моделей.

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

программируйте на уровне интерфейсов, а не реализаций

Изменяется у нас метод void drive(), с него и начнем и создадим интерфейс Drivable c двумя классами, которые его реализуют: один для полноприводных машин, второй для переднеприводных.

Теперь изменим наш главный класс AudiCar и классы, которые от него наследуются.

Как видно из кода, метод void drive() теперь не зависит от конкретной реализации класса модели машины. Главный метод тоже подвергнется небольшим изменениям:

Если Вы заметили, то теперь мы программируем на уровне супертипов (AudiCar audiA3 вместо AudiA3 audiA3). В результате выполнения этого кода получим:

Rear wheel drive
Full wheel drive

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

И немного изменим реализацию классов конкретных моделей машин:

Теперь мы можем изменять поведение нашей машины на ходу:

Все работает так как мы и задумывали:

Full wheel drive
Rear wheel drive

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



Паттерн Стратегия полный код примера:

Как Вы могли заметить при всех своих плюсах у паттерна Стратегия есть один существенный недостаток – обилие дополнительных классов.

Site Footer