Skip to main content

责任链模式 (Chain of Responsibility)

场景问题​

问题案例​

考虑一个请假审批系统,普通员工请假需要组长审批,组长请假需要经理审批,经理请假需要总监审批。如何灵活扩展审批流程?

不用模式的解决方案​

实现简化版本​

最直接的做法是用if-else语句判断请假天数,决定由谁审批:

public class LeaveRequest {
private int days;
public LeaveRequest(int days) { this.days = days; }
public int getDays() { return days; }
}

public class Approver {
public void approve(LeaveRequest request) {
if (request.getDays() <= 1) {
System.out.println("组长审批");
} else if (request.getDays() <= 3) {
System.out.println("经理审批");
} else {
System.out.println("总监审批");
}
}
}

使用示例​

Approver approver = new Approver();
approver.approve(new LeaveRequest(2));

有何问题​

  1. 审批流程不灵活,扩展困难。
  2. 违反开闭原则。
  3. 代码难以维护。

解决方案​

责任链模式的定义​

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

应用责任链模式的思路​

  • 定义抽象处理者,包含处理请求和传递请求的方法。
  • 每个具体处理者持有下一个处理者的引用。
  • 客户端只需将请求交给链头即可。

责任链模式的结构​

  • Handler:抽象处理者,定义处理请求和传递请求的方法。
  • ConcreteHandlerA/B:具体处理者,实现具体处理逻辑。

责任链模式的实现​

// 请求类
public class LeaveRequest {
private int days;
public LeaveRequest(int days) { this.days = days; }
public int getDays() { return days; }
}

// 抽象处理者
public abstract class Approver {
protected Approver next;
public void setNext(Approver next) { this.next = next; }
public abstract void approve(LeaveRequest request);
}

// 具体处理者
public class Leader extends Approver {
public void approve(LeaveRequest request) {
if (request.getDays() <= 1) {
System.out.println("组长审批");
} else if (next != null) {
next.approve(request);
}
}
}
public class Manager extends Approver {
public void approve(LeaveRequest request) {
if (request.getDays() <= 3) {
System.out.println("经理审批");
} else if (next != null) {
next.approve(request);
}
}
}
public class Director extends Approver {
public void approve(LeaveRequest request) {
System.out.println("总监审批");
}
}

使用示例​

public class Client {
public static void main(String[] args) {
Approver leader = new Leader();
Approver manager = new Manager();
Approver director = new Director();
leader.setNext(manager);
manager.setNext(director);
leader.approve(new LeaveRequest(2));
leader.approve(new LeaveRequest(4));
}
}

责任链重写示例​

示例结构​


示例代码​

见上文"责任链模式的实现"部分。


模式讲解​

责任链模式的功能​

  • 动态组合处理链,扩展灵活。
  • 解耦请求发送者和处理者。
  • 满足开闭原则。

实现成接口​

  • 处理者通常定义为接口或抽象类。

使用工厂方法​

  • 可结合工厂方法模式,统一创建处理链。

切换产品簇​

  • 可用于切换不同的处理链,如不同审批流程。

执行时序图​