Поведенческие паттерны решают проблемы взаимодействия элементов внутри системы
Chain of Command - построение цепочки команд, которые обрабатывают полученное значение и передают его друг за другом
Mediator - организация взаимодействия между несколькими компонентами, которые должны быть сильно связаны друг с другом и позволяет модерировать эти взаимодействия
Command - позволяет вывести часть логики в команды. Организует работу объектов не напрямую друг на другом, а в команде
State - позволяет работать с состоянием объекта
Strategy - реализация наборов стратегий, которые взаимозаменяются на лету
Iterator - позволяет реализовать итерирование по древовидным структурам
Template Method - задание шаблонного метода с набором последовательных шагов, которые потом могут применяться к различным схожим системам
Observer - мы подписываемся на определённый элемент в коде и получаем уведомление об его изменении
112** Chain of Command
Это паттерн, который разбивает логику выполнения промежуточных и необязательных команд на отдельную функциональность.
Мы внешний запрос, который приходит к нам в обработчик. Мы понимаем, что нам нужно произвести авторизацию данных, а затем ещё и валидацию получаемых данных
Решение представляет из себя реализацию middleware компонентов, которые будут обрабатывать получаемые данные
Стоит такой подход использовать, если нам нужно сделать код более модульным и разделить обязанности выполнения внутри него (если нам будет не нужен определённый функционал)
113 Mediator
Данный паттерн встречается в основном на фронте, чтобы два разрозненных компонента могли знать друг о друге
EventHandler должен знать о Notification. Notification должен уметь логировать и кешировать. В свою очередь, кэширование должно знать о логах.
Медиатор (посредник) представляет из себя управляющего оркестром, при котором все элементы знают друг о друге
И вот реализация композиции медиатора:
114 Command
Это один из самых частоиспользуемых паттернов в программировании как фронта (смена стейтов), так и в бэке (SEQRS)
Мы имеем контроллер, сокеты и сихронизацию, которые каждый раз дёргают UserService. Однако нам нужно реализовать логирование, откат пользователей, очередь определённых задач или отложенное добавление данных (чтобы не перенагружать сервис). Чтобы сделать это, мы могли бы добавить часть этой реализации в каждый из классов
Однако можно воспользоваться более простым способом решения проблемы: создать один класс, который выполнял бы все задачи
И вот так реализуется паттерн команды
Это самый рекомендуемый паттерн к использованию, так как его часто можно встретить в высоконагруженных сервисах.
115 State
Паттерн State определяет, как мы можем работать с состоянием определённой логики в приложении.
В примере показан пример реализации состояний прямо внутри документа и подобное представление в CRM
Вместо того, чтобы хранить все состояния внутри нашего документа, мы можем в документ добавить ссылку на текущее состояние. Логика переходов между состояниями реализуется в самих классах состояния элемента
Так выглядит реализация состояний документа в процессе жизненного цикла статей
116 Strategy
Стратегия подразумевает под собой поиск похожих алгоритмов внутри программы и выделение их в отдельные классы, взаимозаменяя друг друга
Конкретно тут в качестве примера для применения стратегии выделяется ситуация, когда нам нужно реализовать авторизацию. У нас была сначала регистрация через JWT, а потом нам сказали сделать через GitHub, а уже потом добавить через гугл и фэйсбук. Логика авторизации примерно похожа, поэтому нам её нужно собирать.
Решить проблему мы можем через создание интерфейса для определения стратегии и выбора стратегии в этой аутентификации
117 Iterator
Паттерн итератор позволяет нам выполнять определённые задачи по определённому нами приоритету
Мы имеем систему, в которой мы имеем определённые задачи, которые нужно решать по степени их важности и, желательно, связанно друг с другом
Решить проблему мы можем через явное задание тасклиста, который содержит в себе таски. К тасклисту будет обращаться итератор и выполнять сначала приоритетные таски, а затем малоприоритетные (в позиции по убыванию)
118 Template Method
Паттерн шаблона говорит нам об абстрагировании повторяющейся логики
Конкретно мы имеем такую проблему: нам из формы нужно отправить данные в два разных АПИ, логика которых схожа, но немного отличается
Чтобы не городить дублирование кода в самой форме, мы можем сделать отдельный абстрактный класс, который будет за нас хранить в себе логику отправки данных на разные АПИ. Единственное, что нужно будет сделать из формы - это вызвать SaveForm, что крайне удобно
Используем этот паттерн, когда мы имеем одинаковые шаги в логике, но они отличаются немного в реализации
119 Observer
Паттерн обсёрвера подразумевает под собой то, что мы создаём класс, который уведомляет другую логику о том, что ей нужно выполниться (например, выполнять функцию при срабатывании ивентлистенера)
Конкретно тут нужно сделать так, чтобы лид сервис отправлял уведомления пользователю о новых действиях лида
Решить проблему можно через создание отдельных обсёрверов со своим нотифаем под каждый сервис. А так же нужно задать нашего лида в качестве субъекта