НЕ МОЛЧИ!!!    Сделай что-нибудь,
чтобы остановить войну России в Украине.
...бойтесь людей равнодушных - именно с их молчаливого согласия происходят все самые ужасные преступления на свете.   ("Репортаж с петлёй на шее")

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

Описывается поведенческий шаблон проектирования Strategy, его применение, пример реализации шаблона в коде.

Содержание

  • Применение
  • Реализация
  • Итоги

Применение

Думаю, многим приходилось сталкиваться с ситуацией, когда при создании или сопровождении приложения жизнь заставляет дополнять основную обработку мелкими вариациями. Если таких отклонений немного, доработать несложно. А если много? А если изменения существенно затрагивают оттестированную бизнес-логику, над которой работало несколько програмистов? В этом случае при условии, что основной алгоритм поведения объекта неизменный, удобно вынести различия алгоритма обработки в отдельные классы, которые доступны для основного алгоритма по ссылке. Чем удобно?

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

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

Реализация

В реализации шаблона Strategy используются такие компоненты:

  • IStrategy — единый интерфейс классов конкретной обработки, декларирует методы конкретной обработки.
  • Strategy1 — класс, реализующий одну из дополнительных обработок;
  • Strategy2 — класс, реализующий ещё одну из дополнительных обработок;
  • Context — класс, осуществлющий основную часть алгоритма обработки запросов клиента, инкапсулирует ссылку на один из классов конкретной дополнительной обработки.

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

public interface IStrategy
{
    public function execute(): string;
}

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

class Strategy1 implements IStrategy
{
    public function execute(): string 
    {
        echo "Выполняется алгоритм стратегии 1.";
    }
}
class Strategy2 implements IStrategy
{
    public function execute(): string
    {
        echo "Выполняется алгоритм стратегии 2.";
    }
}

Ниже приведена программная заглушка класса запроса

class Request
{
    // Данные запроса (заглушка)
}

Объявим класс, реализующий основную обработку запросов клиента. Как было сказано, ему должна быть доступна ссылка на объект дополнительной обработки.

class Context
{
    private IStrategy $strategy;

    public function __construct(IStrategy $strategy)
    {
        $this->$strategy = $strategy;
    }

    //позволяет динамически менять алгоритм обработки
    public SetStrategy(IStrategy $strategy): void
    {
        $this->$strategy = $strategy;
    }

    public processRequest(Request $request): string
    {
       // основная логика обработки запроса

       //a теперь производим дополнительную новую обработку
       return $this.strategy->execute();
    }
}

Ещё раз обращаю внимание на важную деталь — при создании экземпляра класса Context ему надо передавать ссылку на вариант стратегии обработки запроса.

UML диаграмма классов шаблона Strategy выглядит так.

шаблон проектирования Strategy
UML диаграмма классов шаблона проектирования Strategy

Итоги

Было продемонстрировано, как шаблон проектирования Strategy может упростить жизнь программиста при внесении изменений в алгоритм обработки запросов. Кроме несомненных достоинств:

  • возможность упростить класс обработки запросов за счет вынесения части алгоритма в другие компоненты;
  • простота модификации приложения, поскольку различия в обработке вынесены в отдельные классы;
  • возможность динамически изменять обработку на «лету».

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

Перейти к списку шаблонов проектирования.