责任链模式, 又称职责链模式, 为了避免将请求发送者和多个请求处理者耦合在一起, 将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链, 当有请求发送时, 可将请求沿着这条链传递, 直到有对象处理它为止

责任链模式结构

  • 抽象处理者: 定义一个处理请求的接口, 包含一个抽象处理方法和一个后继连接
  • 具体处理者: 实现抽象处理者的处理方法, 判断是否能够处理本次请求, 如果可以处理请求则处理, 否则将该请求转发给它的后继者
  • 客户类: 创建处理链, 并向链头的的处理者提交请求, 不关心处理细节和请求的传递过程

责任链模式实现

假设现在有以下场景, 现在需要开发一个请假系统, 请一天的假需要组长同意, 1~3天的假需要部门经理同意, 3~7天的假需要总经理同意

// 请求
public class LeaveRequest {
private String name;

private int num;

private String content;

public LeaveRequest(String name, int num, String content) {
this.name = name;
this.num = num;
this.content = content;
}

public String getName() {
return name;
}

public int getNum() {
return num;
}

public String getContent() {
return content;
}
}


// 抽象处理者
public abstract class Handler {
protected final static int NUM_ONE = 1;
protected final static int NUM_THREE = 3;
protected final static int NUM_SEVEN = 7;

private int numStart;
private int numEnd;

private Handler nextHandler;

public Handler(int numStart) {
this.numStart = numStart;
}

public Handler(int numStart, int numEnd) {
this.numStart = numStart;
this.numEnd = numEnd;
}

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

protected abstract void handleLeaveRequest(LeaveRequest leave);

public final void submit(LeaveRequest leave) {
this.handleLeaveRequest(leave);
if (this.nextHandler != null && leave.getNum() > this.numEnd) {
this.nextHandler.submit(leave);
} else {
System.out.println("流程结束");
}
}
}

// 具体处理者
public class GroupLeader extends Handler {
public GroupLeader() {
super(0, Handler.NUM_ONE);
}

protected void handleLeave(LeaveRequest leave) {
System.out.println(leave.getName() + "请假" + leave.getNum + "天, " + leave.getContent());
System.out.println("组长审批: 同意")
}
}

// 具体处理者
public class Manager extends Handler {
public Manager() {
super(Handler.NUM_ONE, Handler.NUM_THREE);
}

protected void handleLeave(LeaveRequest leave) {
System.out.println(leave.getName() + "请假" + leave.getNum + "天, " + leave.getContent());
System.out.println("部门经理审批: 同意")
}
}

// 具体处理者
public class GeneralManager extends Handler {
public GeneralManager() {
super(Handler.NUM_THREE, Handler.NUM_SEVEN);
}

protected void handleLeave(LeaveRequest leave) {
System.out.println(leave.getName() + "请假" + leave.getNum + "天, " + leave.getContent());
System.out.println("经理审批: 同意")
}
}

public class Client {
public static void main(String[] args) {
LeaveRequest leave = new LeaveRequest();

GroupLeader groupLeader = new GroupLeader();
Manager manager = new Manager();
GeneralManager generalManager = new GeneralManager();

groupLeader.setNextHandler(manager);
manager.setNextHandler(generalManager);

groupLeader.submit(leave);
}
}

优点:

  • 降低了对象之间的耦合度
  • 增强了系统的可扩展性
  • 增强了给对象指派职责的灵活性
  • 责任链简化了对象之间的连接
  • 责任分担

缺点:

  • 不能保证每个请求都被处理
  • 对比较长的职责链, 请求的处理可能涉及到多个处理对象, 系统性能会受到影响
  • 职责链建立的合理性要靠客户端来保证, 增加了客户端的复杂性, 可能会因为职责链的错误设置而导致系统出错, 如可能会造成循环调用