Найти в Дзене
🚲Макс💻Код🩼

Разбор паттерна цепочка ответственностей

Оглавление

Паттерн "Цепочка обязанностей" (Chain of Responsibility) относится к поведенческим паттернам проектирования. Он позволяет передавать запрос по цепочке обработчиков, где каждый обработчик может обработать запрос или передать его следующему в цепочке. Это особенно удобно для задач, связанных с обработкой событий или запросов, когда порядок и количество возможных обработчиков невозможно определить заранее.

Этот паттерн полезен для организаций сценариев, где множество объектов могут обрабатывать запрос, но точный объект, который должен обработать запрос, заранее неизвестен.

Рассмотрим сценарий, где у нас есть система для обработки различных типов запросов (например, запросы на техническую поддержку, запросы на получение информации и жалобы). Без использования Chain of Responsibility, код может быть громоздким и сложным для поддержки:

public class RequestHandler {
public void handleRequest(Request request) {
if (request.getType().equals("support")) {
// Логика обработки технической поддержки
} else if (request.getType().equals("info")) {
// Логика обработки запросов на информацию
} else if (request.getType().equals("complaint")) {
// Логика обработки жалоб
}
}
}

Паттерн "Цепочка обязанностей" позволяет устранить громоздкие условные операторы и сделать код более модульным. Мы создадим абстрактный класс или интерфейс для обработчиков запросов и конкретные реализации для каждого типа запросов.

Определение Интерфейса Обработчика

public interface RequestHandler {
void setNextHandler(RequestHandler nextHandler);
void handle(Request request);
}

Реализация Абстрактного Класса

public abstract class AbstractRequestHandler implements RequestHandler {
protected RequestHandler nextHandler;
@Override
public void setNextHandler(RequestHandler nextHandler) {
this.nextHandler = nextHandler;
}
protected void passToNext(Request request) {
if (nextHandler != null) {
nextHandler.handle(request);
}
}
}

Конкретные Реализации Обработчиков

@Component
public class SupportHandler extends AbstractRequestHandler {
@Override
public void handle(Request request) {
if (request.getType().equals("support")) {
System.out.println("Handling support request.");
} else {
passToNext(request);
}
}
}

@Component
public class InfoHandler extends AbstractRequestHandler {
@Override
public void handle(Request request) {
if (request.getType().equals("info")) {
System.out.println("Handling info request.");
} else {
passToNext(request);
}
}
}

@Component
public class ComplaintHandler extends AbstractRequestHandler {
@Override
public void handle(Request request) {
if (request.getType().equals("complaint")) {
System.out.println("Handling complaint.");
} else {
passToNext(request);
}
}
}

Составление Цепочки Обработчиков

Мы можем собрать цепочку обработчиков в конфигурационном классе Spring.

@Configuration
public class RequestHandlerConfig {
@Bean
public RequestHandler requestHandlerChain(SupportHandler supportHandler, InfoHandler infoHandler, ComplaintHandler complaintHandler) {
supportHandler.setNextHandler(infoHandler);
infoHandler.setNextHandler(complaintHandler);
return supportHandler;
}
}

Пример использования

@SpringBootApplication
public class ChainOfResponsibilityExample {
public static void main(String[] args) {
ApplicationContext context = SpringApplication.run(ChainOfResponsibilityExample.class, args);
RequestHandler requestHandler = context.getBean(RequestHandler.class);
Request supportRequest = new Request("support");
Request infoRequest = new Request("info");
Request complaintRequest = new Request("complaint");
requestHandler.handle(supportRequest);
requestHandler.handle(infoRequest);
requestHandler.handle(complaintRequest);
}
}

public class Request {
private String type;
public Request(String type) {
this.type = type;
}
public String getType() {
return type;
}
}

Преимущества

1. Снижение Связанности: Обработчики могут быть добавлены или удалены без изменения существующих обработчиков или их порядка.

2. Расширяемость: Легко добавлять новые типы обработчиков.

3. Гибкость: Порядок обработки запросов можно легко изменять в конфигурации.

Паттерн "Цепочка обязанностей" предоставляет мощный инструмент для динамического управления обработкой запросов. Использование Spring упрощает создание и конфигурацию цепочек обработчиков, делая код более гибким и легко поддерживаемым. Этот паттерн идеально подходит для систем, где запросы могут обрабатываться разными способами в зависимости от их типа и где обработчики легко могут быть изменены или заменены.