跳到主要内容

责任链模式

介绍

责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它允许多个对象处理同一个请求,而客户端不必知道哪个对象最终会处理该请求。请求沿着一条链传递,直到有一个对象处理它为止。

原理

责任链模式的核心原理包括:

  1. 抽象处理者:定义处理请求的接口,包含一个指向下一个处理者的引用
  2. 具体处理者:实现抽象处理者的接口,决定是否处理请求,如果不处理则传递给下一个处理者
  3. 客户端:创建处理链,并向链的第一个处理者提交请求

图示

责任链模式的核心结构包括抽象处理者、具体处理者和客户端。以下是责任链模式的UML类图和工作流程图示:

UML类图

+----------------+        +----------------+
| Handler |<----| Client |
+----------------+ +----------------+
| - nextHandler | | + main() |
| + setNextHandler()| | |
| + handleRequest()| | |
+-------^--------+ +----------------+
|
|
+-------+--------+ +-------------+ +-------------+
| ConcreteHandlerA|-->|ConcreteHandlerB|-->|ConcreteHandlerC|
+----------------+ +-------------+ +-------------+
| + handleRequest()| | + handleRequest()| | + handleRequest()|
+----------------+ +-------------+ +-------------+

工作流程图

Client
|
v
+----------------+ 处理请求? +----------------+
| ConcreteHandlerA|------------>| ConcreteHandlerB|
+----------------+ 否 +----------------+
| 是 | 否
v v
处理请求并返回 +----------------+
| ConcreteHandlerC|
+----------------+
| 否
v
无处理者,返回错误

执行流程示例

请求 5 → ConcreteHandlerA (处理)
请求 15 → ConcreteHandlerA → ConcreteHandlerB (处理)
请求 25 → ConcreteHandlerA → ConcreteHandlerB → ConcreteHandlerC (处理)
请求 35 → ConcreteHandlerA → ConcreteHandlerB → ConcreteHandlerC → 无处理者 (错误)

代码示例

抽象处理者

public abstract class Handler {
protected Handler nextHandler;

public void setNextHandler(Handler nextHandler) {
this.nextHandler = nextHandler;
}

public abstract void handleRequest(int request);
}

具体处理者

public class ConcreteHandlerA extends Handler {
@Override
public void handleRequest(int request) {
if (request >= 0 && request < 10) {
System.out.println("处理者A处理请求 " + request);
} else if (nextHandler != null) {
nextHandler.handleRequest(request);
} else {
System.out.println("没有处理者能处理请求 " + request);
}
}
}

public class ConcreteHandlerB extends Handler {
@Override
public void handleRequest(int request) {
if (request >= 10 && request < 20) {
System.out.println("处理者B处理请求 " + request);
} else if (nextHandler != null) {
nextHandler.handleRequest(request);
} else {
System.out.println("没有处理者能处理请求 " + request);
}
}
}

public class ConcreteHandlerC extends Handler {
@Override
public void handleRequest(int request) {
if (request >= 20 && request < 30) {
System.out.println("处理者C处理请求 " + request);
} else if (nextHandler != null) {
nextHandler.handleRequest(request);
} else {
System.out.println("没有处理者能处理请求 " + request);
}
}
}

客户端代码

public class Client {
public static void main(String[] args) {
Handler handlerA = new ConcreteHandlerA();
Handler handlerB = new ConcreteHandlerB();
Handler handlerC = new ConcreteHandlerC();

// 设置责任链
handlerA.setNextHandler(handlerB);
handlerB.setNextHandler(handlerC);

// 提交请求
handlerA.handleRequest(5);
handlerA.handleRequest(15);
handlerA.handleRequest(25);
handlerA.handleRequest(35);
}
}

解决方案

应用场景

  1. 请求处理流程:如HTTP请求处理、日志级别处理
  2. 异常处理:不同级别的异常由不同的处理器处理
  3. 审批流程:如请假审批、报销审批
  4. 事件传播:UI事件的冒泡和捕获
  5. 过滤器链:如Web中的过滤器

最佳实践

  1. 保持处理者简洁:每个处理者只处理一类请求
  2. 避免过长的责任链:过长的责任链会导致性能问题和调试困难
  3. 设置默认处理者:确保每个请求都能被处理
  4. 使用工厂模式创建责任链:结合工厂模式管理责任链的创建
  5. 考虑使用注解或配置文件:在大型应用中,通过注解或配置文件定义责任链

优缺点

优点

  • 解耦请求发送者和接收者
  • 灵活性高,可以动态组合处理者
  • 符合开闭原则
  • 易于扩展新的处理者

缺点

  • 请求可能不被处理
  • 责任链过长会影响性能
  • 调试困难,难以跟踪请求的处理过程

工具推荐

  1. Spring Framework:提供HandlerInterceptor接口实现责任链模式
  2. Java Servlet API:Filter接口基于责任链模式
  3. Apache Commons Chain:专门实现责任链模式的库
  4. Netty:ChannelHandlerContext实现责任链模式
  5. RxJava/RxAndroid:提供操作符实现链式调用