Рубріки: Основы

Обычного наследования недостаточно: зачем использовать паттерн «Стратегия» в разработке

Николай Коваленко

Как пишут в Википедии, стратегия — это поведенческий шаблон проектирования, предназначенный для определения семейства алгоритмов, инкапсуляции каждого из них и обеспечения их взаимозаменяемости.

Вот так выглядит стратегия в UMLангл. Unified Modeling Language — унифицированный язык моделирования:

Непонятно ровным счетом ничего, скажут многие и будут правы.

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

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

Что представляет собой паттерн «Стратегия»

Итак, стратегия — это не что иное, как обычное делегирование с возможностью выбора конкретной реализации делегата с определенным интерфейсом из существующего набора.

Поведение объекта делегируется другому объекту, который реализует это поведение. В итоге делегат реализует поведение и является зависимостью для объекта, поведение которого он реализует.

Таким образом выполняется правило единой ответственности класса (объект отвечает за набор данных, а реализация поведения — за то, как эти данные себя ведут), что очень хорошо сказывается на размере классов, количестве зависимостей, дублировании кода и дальнейшей поддержке проекта.

Так как все делегаты, реализующие поведение объекта, имеют один интерфейс, то не составляет труда обеспечить возможность реализации различного поведения для каждого из объектов посредством внедрения требуемой реализации поведения. Сделать это можно на этапе создания объекта, просто передав в конструктор требуемый экземпляр реализации поведения.

Зачем нужен паттерн «Стратегия»

Все это, конечно, хорошо, но зачем все это нужно? Ведь такая реализация приводит к тому, что мы усложняем статический анализ кода, пряча конкретную реализацию поведения за интерфейсом и используемым механизмом внедрения зависимостей.

Реализация паттерна «Стратегия» позволяет более гибко использовать полиморфизм поведения объекта без необходимости дублирования кода и наращивания уровней иерархии наследования.

Чем стратегия лучше переопределения методов в наследниках?

Можно заметить, что все преимущества паттерна «Стратегия» можно реализовать обычным наследованием, если перекрывать в наследнике реализацию поведенческого метода родителя. Но наследование не позволяет получить ни поведение не из родителя, ни различное поведение от двух разных родителей.

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

Реализация паттерна «Стратегия» лишена этого недостатка. Всегда можно применить любой набор существующих поведений и расширять его до бесконечности без необходимости каких-либо изменений структуры приложения.

Когда применять паттерн «Стратегия»

Не стоит рассматривать паттерн «Стратегия» как обязанность. Если есть поведение, то должен быть интерфейс, его реализация, и эта реализация должна внедряться как зависимость. Ничего подобного. Нужно идти от простого к сложному, всегда оставляя место для шага вперед.

Начать можно с обычного делегирования, чтобы отделить поведение от данных и вынести реализацию поведения в отдельный объект. Если в будущем появится необходимость реализации нескольких вариантов поведения, можно реализовать интерфейс для поведения и перейти к паттерну «Стратегия».

Такой подход не требует больших усилий и существенных архитектурных изменений проекта.

Программная реализация паттерна «Стратегия»

Реализацию на PHP приводить не буду, так как она довольно простая, если понять суть применения паттерна на практике. Проблему может вызвать только необходимость иметь что-то вроде фабрики или фабричного метода для создания нужной реализации конкретного поведения объекта. Но это можно легко сделать при помощи механизма внедрения зависимостей (dependency injection), без которого не обходится ни один проект.

Для тех, кто все прочел и так и не понял, как работает паттерн «Стратегия» и для чего его применять, предлагаю посмотреть видео, в котором очень понятно и доступно (правда, на английском языке) излагается суть паттерна, особенности его применения и программной реализации. Пример кода в самом конце видео. Приятного просмотра.

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

Спасибо, что дочитали до конца. Надеюсь, информация была полезна.

Читайте также: Принцип SOLID, который все понимают неправильно: что такое единая ответственность в разработке

Это текст из личного блога, опубликованный с разрешения автора.

If you have found a spelling error, please, notify us by selecting that text and pressing Ctrl+Enter.

Останні статті

Токсичные коллеги. Как не стать одним из них и прекратить ныть

В благословенные офисные времена, когда не было большой войны и коронавируса, люди гораздо больше общались…

07.12.2023

Делать что-то впервые всегда очень трудно. Две истории о начале карьеры PM

Вот две истории из собственного опыта, с тех пор, когда только начинал делать свою карьеру…

04.12.2023

«Тыжпрограммист». Как люди не из ІТ-отрасли обесценивают профессию

«Ты же программист». За свою жизнь я много раз слышал эту фразу. От всех. Кто…

15.11.2023

Почему чат GitHub Copilot лучше для разработчиков, чем ChatGPT

Отличные новости! Если вы пропустили, GitHub Copilot — это уже не отдельный продукт, а набор…

13.11.2023

Как мы используем ИИ и Low-Code технологии для разработки IT-продукта

Несколько месяцев назад мы с командой Promodo (агентство инвестировало в продукт более $100 000) запустили…

07.11.2023

Университет или курсы. Что лучше для получения IT-образования

Пару дней назад прочитал сообщение о том, что хорошие курсы могут стать альтернативой классическому образованию.…

19.10.2023