Паттерны проектирования Поведенческие шаблоны
25 июня 2021

Паттерны проектирования
Поведенческие шаблоны

Стратегия, состояние, команда, цепочка обязанностей.
Стратегия (Strategy)

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

  • Когда вам нужно использовать разные вариации какого-то алгоритма внутри одного объекта.
  • Когда у вас есть множество похожих классов, отличающихся только некоторым поведением.
  • Когда вы не хотите обнажать детали реализации алгоритмов для других классов.
  • Когда различные вариации алгоритмов реализованы в виде развесистого условного оператора. Каждая ветка такого оператора представляет собой вариацию алгоритма.
Плюсы vs. Минусы

Плюсы:
  • Горячая замена алгоритмов на лету.
  • Изолирует код и данные алгоритмов от остальных классов.
  • Уход от наследования к делегированию.
  • Реализует принцип открытости/закрытости.

Минусы:
  • Усложняет программу за счёт дополнительных классов.
  • Клиент должен знать, в чём состоит разница между стратегиями, чтобы выбрать подходящую.
Вези меня, вези!
Стой! Куда же ты!?
Давайте внесем корректировки в метод движения автомобиля.

  • if (isRed && isYellow) { StartEngine(); }
  • else if (isRed || isYellow) { Stop(); }
  • else if (isFlashGreen) { CheckDriving(); }
  • else if (isGreen) { KeepDriving(); }
Ну вот, другое дело!
Да что опять-то случилось? Мне же направо, почему не едем?
Состояние (State)

  • Состояние — объект меняет поведение в зависимости от своего состояния, создавая впечатление подмены класса объекта. При этом как правило существует четкий список переходов из одних состояний в другие.
  • Знакомо? Думаю, да.
  • Правильно! Это же конечный автомат (state machine).
  • Контекст не выполняет действия, он делегирует эти обязанности объектам-состояниям
Когда вспомнить о шаблоне Состояние?

  • Когда имеется объект, поведение которого кардинально меняется в зависимости от внутреннего состояния, причём типов состояний много, и они часто меняются.
  • Когда код класса содержит множество больших, похожих друг на друга условных операторов, которые выбирают поведения в зависимости от текущих значений полей класса.
  • Когда используется табличная машина состояний, построенная на условных операторах и приводящая к дублированию кода для похожих состояний и переходов.
Плюсы vs. Минусы

Плюсы:
  • Избавляет от множества больших условных операторов машины состояний.
  • Концентрирует в одном месте код, связанный с определённым состоянием.
  • Упрощает код контекста.

Минусы:
  • Может неоправданно усложнить код, если состояний мало и они редко меняются.
Отличие от Стратегии

Состояние можно рассматривать как надстройку над Стратегией. Оба паттерна используют композицию, чтобы менять поведение основного объекта, делегируя работу вложенным объектам-помощникам. Однако в Стратегии эти объекты не знают друг о друге и никак не связаны. В Состоянии сами конкретные состояния могут переключать контекст.
    Сначала звоним слесарю по номеру …1. Изделие готово? Отлично.
    Теперь звоним логисту по номеру …2. Ага.
    А теперь – бухгалтеру по номеру …3, добавочный 12, пусть денег выделит.
    Сделано.
    - А что с прошлым директором случилось?
    - Телефонной книжкой придавило. Там только добавочных бухгалтера – 165 листов.

        Команда (Command)

        Поведенческий паттерн проектирования, который превращает запросы в объекты, позволяя передавать их как аргументы при вызове методов, ставить запросы в очередь, логировать их, а также поддерживать отмену операций.
        1. Людочка, позвоните, пожалуйста, слесарю, на какой он там стадии?
        2. Потом узнайте, во что нам встанет доставка.
        3. Ну и бухгалтера по результату поставьте в известность.
        4. Да, и еще, скажите бухгалтеру, чтобы на следующий месяц кофе в бюджет заложила.
        5. Спасибо.

        Команда (Command)

        Когда вспомнить о шаблоне Команда?

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

        Плюсы:
        • Убирает прямую зависимость между объектами, вызывающими операции, и объектами, которые их непосредственно выполняют.
        • Позволяет реализовать простую отмену и повтор операций.
        • Позволяет реализовать отложенный запуск операций.
        • Позволяет собирать сложные команды из простых.
        • Реализует принцип открытости/закрытости.

        Минусы:
        • Усложняет код программы из-за введения множества дополнительных классов.
        Цепочка обязанностей (CoR – Chain of Responsibility).

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

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

          Плюсы:
          • Уменьшает зависимость между клиентом и обработчиками.
          • Реализует принцип единственной обязанности.
          • Реализует принцип открытости/закрытости.

          Минусы:
          • Запрос может остаться никем не обработанным.
          Закрепим

          • Стратегия предлагает определить семейство схожих алгоритмов, которые часто изменяются или расширяются, и вынести их в собственные классы, называемые стратегиями.
          • Состояние позволяет объектам менять поведение в зависимости от своего состояния. Извне создаётся впечатление, что изменился класс объекта.
          • Команда превращает запросы в объекты, позволяя передавать их как аргументы при вызове методов.
          • Цепочка обязанностей позволяет передавать запросы последовательно по цепочке обработчиков.
          Вам также может быть интересно