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

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

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

Содержание

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

Применение

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

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

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

Реализация

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

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

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

public interface IStrategy
{
    public function Execute();
}

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

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

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

class Context
{
    private $strategy;

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

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

    public processRequest(Request $request)
    {
       //производится основная часть обработки

       return $result = $strategy->execute();
    }
}

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

Итоги

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

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

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

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