Шаблон цепочки обязанностей
Шаблон цепочки обязанностей создаёт цепочку объектов-получателей для запроса. Этот шаблон устраняет связывание отправителя и получателя запроса в зависимости от типа запроса. Этот тип шаблона проектирования относится к поведенческим шаблонам.
Шаблон цепочки обязанностей соединяет несколько обработчиков (обрабатывающих объектов) в цепочку, позволяя передавать запрос по цепочке до тех пор, пока какой-либо обработчик не обработает его.
Шаблон цепочки обязанностей позволяет нескольким объектам иметь возможность обработать запрос, тем самым избегая связывания отправителя и получателя запроса. Эти объекты соединяются в цепочку, и запрос передаётся по цепочке.
Введение
назначение
Позволяет передавать запрос по цепочке обработчиков до тех пор, пока запрос не будет обработан.
Основные решаемые проблемы
- Разделяет отправителя и получателя запроса, позволяя нескольким объектам иметь возможность получить запрос, при этом отправителю не нужно знать, какой объект будет его обрабатывать.
Сценарий использования
- Когда есть несколько объектов, которые могут обработать запрос, и то, какой конкретный объект его обработает, определяется во время выполнения.
- Когда нужно отправить запрос одному из нескольких объектов, не указывая явно получателя.
Подход к реализации
- Определите интерфейс обработчика: Все обработчики должны реализовывать один и тот же интерфейс.
- Создайте конкретные обработчики: Конкретные классы, реализующие интерфейс, содержащие логику обработки запроса и ссылку на следующий обработчик в цепочке.
Ключевой код
- Интерфейс Handler: Определите метод для обработки запросов.
- Класс ConcreteHandler: Реализует интерфейс Handler, содержит логику обработки запроса и ссылку на следующий обработчик.
Пример приложения
- Горячая картошка: Поведение передачи в игре, пока музыка не остановится.
- Всплытие событий: В JavaScript события начинаются с самого конкретного элемента и распространяются вверх уровень за уровнем.
- Веб-серверПримеры включают Apache Tomcat, обрабатывающий кодировку символов, перехватчики Struts2 и Servlet-фильтры.
Преимущества
- Снижение связанности: Разъедините отправителя и получателя.
- Упрощение объектов: объекту не нужно знать структуру цепочки.
- Гибкость: динамически добавлять или удалять обязанности, изменяя участников или порядок цепочки.
- Легко расширять: удобно добавлять новые классы обработчиков запросов.
Недостатки
- Запрос не обработан: нет гарантии, что запрос будет получен обработчиком в цепочке.
- Влияние на производительность: может влиять на производительность системы, отладка затруднена, может привести к циклическим вызовам.
- Сложно наблюдать: характеристики времени выполнения неочевидны, что может затруднить отладку.
Рекомендации по использованию
- При обработке запроса, если есть несколько потенциальных обработчиков, рассмотрите использование паттерна «Цепочка обязанностей».
- Убедитесь, что каждый обработчик в цепочке чётко знает, как передать запрос следующему звену цепочки.
Примечания
- В Java Web-разработке паттерн «Цепочка обязанностей» широко используется, например, в цепочках фильтров, перехватчиках и т. д.
Структура
В основном он включает следующие ключевые роли:
Абстрактный обработчик:
- Определяет интерфейс для обработки запросов, обычно содержащий метод для обработки запроса (например,
handleRequest) и ссылка на следующий обработчик (преемник).
- Определяет интерфейс для обработки запросов, обычно содержащий метод для обработки запроса (например,
Конкретный обработчик:
- Реализует интерфейс абстрактного обработчика и отвечает за обработку запросов. Если он может обработать запрос, он обрабатывает его напрямую; в противном случае он передаёт запрос следующему обработчику.
Клиент:
- Создаёт объекты обработчиков и соединяет их в цепочку обязанностей. Обычно клиенту достаточно лишь отправить запрос первому обработчику в цепочке, не заботясь о конкретной обработке запроса.
Реализация
Мы создаём абстрактный классAbstractLoggerс детализированными уровнями логирования. Затем мы создаём три типа логгеров, все расширяютAbstractLogger. Каждый логгер проверяет, принадлежит ли уровень сообщения его собственному уровню; если да, он выводит его соответствующим образом; в противном случае он не выводит и передаёт сообщение следующему логгеру.
Шаг 1
Создайте абстрактный класс логгера.
AbstractLogger.java
Шаг 2
Создайте классы сущностей, которые расширяют класс logger.
ConsoleLogger.java
ErrorLogger.java
FileLogger.java
Шаг 3
Создайте различные типы логгеров. Назначьте им разные уровни ошибок и установите следующий логгер в каждом логгере. Следующий логгер в каждом логгере представляет часть цепочки.
ChainPatternDemo.java
Шаг 4
Выполните программу, выведите результаты:
Standard Console::Logger: This is an information. File::Logger: This is a debug level information. Standard Console::Logger: This is a debug level information. Error Console::Logger: This is an error information. File::Logger: This is an error information. Standard Console::Logger: This is an error information.Другие расширения