Java Behavioral 行为型模式之 Chain of Responsibility 责任链模式

54 阅读5分钟

Java Behavioral 行为型模式之 Chain of Responsibility 责任链模式

  • 责任链模式允许将请求沿着一条若干个处理者的链上进行传递,每个处理者都有机会处理请求,直到请求被处理或到达链的末端
  • 简化了对象之间的连接,将责任合理分担到每个类(注意明确职责范围,避免职责重叠或遗漏),每个类只需要处理自己该处理的工作,降低了对象之间的耦合度,增强了系统的灵活性和扩展性
  • 通常情况下如果一个处理者不能处理请求,它会将请求转发给下一个处理者,如果处理了请求了,那么这个流程就结束了,不过有些责任链模式,每个处理者都有可能参与处理请求,通常这种责任链被称为 Interceptor 拦截器或者 Filter 过滤器,它可以让每个处理者都做一部分工作
  • 过长的责任链会影响性能,应尽量保持链的长度适中,同时也要确保责任链中没有循环引用,否则会导致无限循环
  • 设计处理者时,可以尽可能地考虑它们的可插拔性,使得系统易于扩展和维护

处理者抽象类

public abstract class Processor {
    //下一个处理者
    protected Processor nextProcessor;
    //设置下一个处理者
    public void setNextProcessor(Processor nextProcessor) {
        this.nextProcessor = nextProcessor;
    }
    //自身处理逻辑
    public abstract void processRequest(Request request);
}

若干个实际处理者

public class AProcessor extends Processor {
    @Override
    public void processRequest(Request request) {
        if (1 <= request.code && request.code < 3) {
            System.out.println("组长审批通过,请假 3 天以内,不含 3 天,实际 " + request.code + " 天");
        } else {
            //给下一个处理者设置处理请求,没有则流程结束
            if (nextProcessor != null) {
                nextProcessor.processRequest(request);
            } else {
                System.out.println("组长后面没有下一个处理者,无法处理 " + request.code + " 天");
            }
        }
    }
}
//
public class BProcessor extends Processor {
    @Override
    public void processRequest(Request request) {
        if (3 <= request.code && request.code < 5) {
            System.out.println("经理审批通过,请假 5 天以内,不含 5 天,实际 " + request.code + " 天");
        } else {
            //给下一个处理者设置处理请求,没有则流程结束
            if (nextProcessor != null) {
                nextProcessor.processRequest(request);
            } else {
                System.out.println("经理后面没有下一个处理者,无法处理 " + request.code + " 天");
            }
        }
    }
}
//
public class CProcessor extends Processor {
    @Override
    public void processRequest(Request request) {
        if (5 <= request.code && request.code < 7) {
            System.out.println("总监审批通过,请假 7 天以内,不含 7 天,实际 " + request.code + " 天");
        } else {
            //给下一个处理者设置处理请求,没有则流程结束
            if (nextProcessor != null) {
                nextProcessor.processRequest(request);
            } else {
                System.out.println("总监后面没有下一个处理者,无法处理 " + request.code + " 天");
            }
        }
    }
}

使用

public static void main(String[] args) {
    //创建处理者
    Processor aProcessor = new AProcessor();//组长
    Processor bProcessor = new BProcessor();//经理
    Processor cProcessor = new CProcessor();//总监
    //设置责任链
    aProcessor.setNextProcessor(bProcessor);
    bProcessor.setNextProcessor(cProcessor);
    //发送请求
    Request request1 = new Request(1,"请假 1 天");
    Request request2 = new Request(2,"请假 2 天");
    Request request3 = new Request(3,"请假 3 天");
    Request request4 = new Request(4,"请假 4 天");
    Request request5 = new Request(5,"请假 5 天");
    Request request6 = new Request(6,"请假 6 天");
    Request request7 = new Request(7,"请假 7 天");
    aProcessor.processRequest(request1);
    aProcessor.processRequest(request2);
    aProcessor.processRequest(request3);
    aProcessor.processRequest(request4);
    aProcessor.processRequest(request5);
    aProcessor.processRequest(request6);
    aProcessor.processRequest(request7);
    //-------- 结果 --------
    //组长审批通过,请假 3 天以内,不含 3 天,实际 1 天
    //组长审批通过,请假 3 天以内,不含 3 天,实际 2 天
    //经理审批通过,请假 5 天以内,不含 5 天,实际 3 天
    //经理审批通过,请假 5 天以内,不含 5 天,实际 4 天
    //总监审批通过,请假 7 天以内,不含 7 天,实际 5 天
    //总监审批通过,请假 7 天以内,不含 7 天,实际 6 天
    //总监后面没有下一个处理者,无法处理 7 天
}

应用场景

  • 1 日志记录:不同级别的日志可以由不同的处理者来处理,比如错误日志可以由专门的错误处理者处理,而信息日志可以由普通的日志处理者处理
  • 2 审批流程:比如 OA 申请流程需要经过多个层级的审批,每个层级的审批人只负责处理自己权限范围内的逻辑,不同级别的审批人组成了一个责任链,根据请求的级别进行审批处理
  • 3 事件处理;按钮的点击事件,事件可以沿着组件的层次结构传递,直到有一个组件处理它为止,比如 Android 中的事件分发
  • 4 异常处理:多层次异常处理,在应用程序中,不同类型的异常可以由不同的处理者处理,形成一个异常处理链

特点

  • 1 降低耦合度:发送者和接收者解耦,处理者之间也松散耦合(只需要知道下一个处理者的存在,而不需要知道链中其他处理者的具体细节),将请求的处理逻辑分散到各个处理者中,每个处理者只负责自己的逻辑,职责单一,使得代码结构更加清晰,易于理解和维护
  • 2 链式结构:请求从链的第一个对象开始,依次传递到下一个对象,直到请求被处理后结束或一直到达链的末端(可以考虑有默认处理逻辑兜底)
  • 3 易于扩展和维护:由于松散耦合的特点,可以很容易地添加、删除或修改处理者去调整职责,对整个系统的结构影响不大,大大增强了系统的灵活性
  • 4 常见应用:Android 的事件分发机制、Android 网络请求库 Retrofit 里的拦截器