基本概念

责任链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。

核心思想:请求沿着处理者链传递,每个处理者决定是处理请求还是将其传递给下一个处理者,形成一个灵活的请求处理机制。

核心结构

  1. Handler(处理者接口):定义处理请求的接口,包含设置下一个处理者和处理请求的方法
  2. ConcreteHandler(具体处理者):实现处理者接口,决定是否处理请求,若不能处理则传递给下一个处理者
  3. Client(客户端):创建处理链,并向链的起始端发送请求

示例说明

场景:员工请假审批系统,不同级别领导处理不同天数的请假申请

  • 组长:处理1天内的请假
  • 部门经理:处理3天内的请假
  • 总经理:处理7天内的请假
  • 超过7天的请假不予批准
  1. 处理者接口
1
2
3
4
5
6
7
8
9
10
11
12

public abstract class Approver {
protected Approver nextApprover; // 下一个处理者

// 设置下一个处理者
public void setNext(Approver nextApprover) {
this.nextApprover = nextApprover;
}

// 处理请假请求
public abstract void processRequest(int days);
}
  1. 组长处理者
1
2
3
4
5
6
7
8
9
10
11
12
13
14

public class TeamLeader extends Approver {
@Override
public void processRequest(int days) {
if (days <= 1) {
System.out.println("组长批准了" + days + "天的请假");
} else if (nextApprover != null) {
nextApprover.processRequest(days); // 传递给下一个处理者
} else {
System.out.println(days + "天的请假申请被拒绝");
}
}
}

  1. 部门经理处理者
1
2
3
4
5
6
7
8
9
10
11
12
13

public class DepartmentManager extends Approver {
@Override
public void processRequest(int days) {
if (days <= 3) {
System.out.println("部门经理批准了" + days + "天的请假");
} else if (nextApprover != null) {
nextApprover.processRequest(days);
} else {
System.out.println(days + "天的请假申请被拒绝");
}
}
}
  1. 总经理处理者
1
2
3
4
5
6
7
8
9
10
11
12

public class GeneralManager extends Approver {
@Override
public void processRequest(int days) {
if (days <= 7) {
System.out.println("总经理批准了" + days + "天的请假");
} else {
System.out.println(days + "天的请假申请超过了最大批准范围,被拒绝");
}
}
}

  1. 测试
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

public class LeaveRequestSystem {
public static void main(String[] args) {
// 创建处理者
Approver teamLeader = new TeamLeader();
Approver departmentManager = new DepartmentManager();
Approver generalManager = new GeneralManager();

// 组装责任链
teamLeader.setNext(departmentManager);
departmentManager.setNext(generalManager);

// 发送请求
teamLeader.processRequest(1); // 组长处理
teamLeader.processRequest(2); // 部门经理处理
teamLeader.processRequest(5); // 总经理处理
teamLeader.processRequest(10); // 超出范围,拒绝
}
}
  1. 执行结果:
1
2
3
4
5
6

组长批准了1天的请假
部门经理批准了2天的请假
总经理批准了5天的请假
10天的请假申请超过了最大批准范围,被拒绝

通过责任链模式,可以创建一个对象链来检查请求,每个对象依次检查请求,处理它或者将它传给链中的下一个对象

类图如下:

责任链模式

总结

优点

  • 解耦请求与处理:发送者无需知道哪个处理者会处理请求,降低耦合度
  • 灵活扩展:可以动态添加或删除处理者,修改处理链顺序
  • 责任分明:处理者各司其职,符合单一职责原则
  • 简化设计:避免在客户端中包含复杂的条件判断逻辑

缺点

  • 请求可能不被处理:若责任链中没有处理者能处理请求,请求会被忽略
  • 性能开销:请求可能需要遍历整个链,影响效率
  • 调试困难:请求的处理路径不明确,调试时难以追踪

使用场景

  • 多级审批流程:如报销审批、请假审批等需要不同级别处理的场景
  • Java异常处理:try-catch-finally机制本质上是责任链的一种应用
  • Servlet过滤器:多个过滤器组成链,依次处理请求
  • 事件处理系统:如GUI中的事件响应链
  • 日志框架:不同级别的日志处理器(DEBUG、INFO、ERROR)组成责任链

责任链模式通过解耦请求发送与处理,使系统更具灵活性和可扩展性,尤其适合处理流程化、层级化的请求场景。