笨蛋学设计模式行为型模式-责任链模式【18】

行为型模式-责任链模式

8.5责任链模式⬆️⬆️⬆️

8.5.1概念

​ 责任链模式定义了一系列的处理器对象,每个处理器对象都包含对链表中下一个处理器对象的引用。在这条请求链条中,每当一个请求发生时,它就会被传递给链表的下一个处理器对象,直到某个处理器对象处理该请求为止。

8.5.2场景

​ 在我们公司内部审批流程中,若某个员工提交了请假申请,需要经过上级的一系列的审批过程,例如小组长审批、部门经理审批、人事部审批、总经理审批等。这些审批过程可以采用责任链模式来实现,将每个审批者看作一个处理器,若某个处理者无法处理该申请,则将该申请传递给下一个处理者,直到有一个处理者同意或拒绝该申请为止。

8.5.3优势 / 劣势

  • 降低耦合度:请求发送者和接收者之间不直接交互,而是通过责任链上的多个对象进行交互,从而降低了它们之间的耦合度
  • 增强灵活性:可以动态地增加或删除处理器,从而改变请求的处理顺序和方式
  • 提高可扩展性:因为每个处理器都只负责处理自己能够处理的请求,所以可以方便地添加新的处理器来处理新的请求类型

  • 请求未处理:若没有任何一个处理器能够处理该请求,则该请求将被忽略
  • 系统性能降低:由于责任链中可能包含大量的处理器,因此可能会影响系统的性能

8.5.4责任链模式可分为

  • 处理者Handler:定义一个处理请求的接口,包含一个处理请求的抽象方法和指向下一个处理者的链接
  • 具体处理者ConcreteHandler:实现处理请求的方法,并判断能否处理请求,若能够处理请求则进行处理,否则将请求传递给下一个处理者
  • 客户端:创建并组装处理者对象链,并将请求发送到链上的第一个处理者

8.5.5责任链模式

java 复制代码
package com.technologystatck.designpattern.mode.chainofresponsibility;


public class ChainOfResponsibility {
    public static void main(String[] args) {
        //创建处理者实例
        ConcreteHandler handlerA = new ConcreteHandler();
        ConcreteHandler handlerB = new ConcreteHandler();
        //...可以继续创建其他处理者实例

        //构建责任链
        handlerA.setNextHandler(handlerB);
        //...可以继续构建责任链

        //发送请求
        Request request = new Request(/*请求参数*/);
        handlerA.handleRequest(request);

    }
}

//1.处理者:定义处理请求的接口
interface Handler{
    //处理请求的方法
    void handleRequest(Request request);
    //设置下一个处理者的方法
    void setNextHandler(Handler nextHandler);
}

//2.具体处理者:实现处理请求
class ConcreteHandler implements Handler{
    private Handler nextHandler;

    //具体处理者自己的判断条件
    private boolean canHandle(Request request){
        //根据具体情况判断是否能够处理请求
        /**
         * 放入自己的判断条件
         */
        return true;
    }
    @Override
    public void handleRequest(Request request) {
        //根据具体情况处理请求,若无法处理则转发给下一个处理者
        if(canHandle(request)){
            //处理请求的逻辑
        }else if(nextHandler !=null){
            nextHandler.handleRequest(request);
        }else{
            //无法处理请求的逻辑,如打印日志等等
        }
    }

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

8.5.6实战

8.5.6.1题目描述

小明所在的公司请假需要在OA系统上发布申请,整个请求流程包括多个处理者,每个处理者负责处理不同范围的请假天数,如果一个处理者不能处理请求,就会将请求传递给下一个处理者,请你实现责任链模式,可以根据请求天数找到对应的处理者。

审批责任链由主管(Supervisor), 经理(Manager)和董事(Director)组成,他们分别能够处理3天、7天和10天的请假天数。如果超过10天,则进行否决。

8.5.6.2输入描述

第一行是一个整数N(1 <= N <= 100), 表示请求申请的数量。

接下来的N行,每行包括一个请求申请的信息,格式为"姓名 请假天数"

8.5.6.3输出描述

对于每个请假请求,输出一行,表示该请求是否被批准。如果被批准/否决,输出被哪一个职级的人批准/否决。

8.5.6.4代码
java 复制代码
package com.technologystatck.designpattern.mode.chainofresponsibility;

import java.util.Scanner;

public class Test {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        int nums=scanner.nextInt();
        scanner.nextLine();

        //组织责任链
        LeaveHandler director = new Director();
        LeaveHandler manager = new Manager(director);
        LeaveHandler supervisor = new Supervisor(manager);

        for(int i=0;i<nums;i++){
            String[] input = scanner.nextLine().split(" ");

            if(input.length==2){
                String name=input[0];
                int days=Integer.parseInt(input[1]);
                LeaveRequest request = new LeaveRequest(name, days);
                supervisor.handleRequest(request);
            }else{
                System.out.println("Invalid input");
                return;
            }
        }
    }
}

//请求类
class LeaveRequest{
    private String name;
    private int days;

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

    public String getName() {
        return name;
    }

    public int getDays() {
        return days;
    }
}
//处理者:定义接口
interface LeaveHandler{
    void handleRequest(LeaveRequest request);
}

//具体处理者:可以有多个,负责具体处理,主要分为Supervisor、Manager、Director
//主管类
class Supervisor implements LeaveHandler{

    //最多3天请假审批
    private static final int MAX_DAYS_SUPERVISOR_CAN_APPROVE=3;
    //设置下一个处理器对象
    private LeaveHandler nextHandler;

    public Supervisor(LeaveHandler nextHandler) {
        this.nextHandler = nextHandler;
    }

    @Override
    public void handleRequest(LeaveRequest request) {
        //若请假的天数小于当前处理者所能审批的最大天数,则直接审批通过,否则继续传递给下一个处理者。
        if(request.getDays()<=MAX_DAYS_SUPERVISOR_CAN_APPROVE){
            System.out.println(request.getName()+" Approved by Supervisor.");
        }else if(nextHandler !=null){
            //若下一个处理器不为空,就直接传给下一个处理器
            nextHandler.handleRequest(request);
        }else{
            System.out.println(request.getName()+"Denied by Supervisor.");
        }
    }
}
//经理类
class Manager implements LeaveHandler{
    //最多7天请假审批
    private static final int MAX_DAYS_SUPERVISOR_CAN_APPROVE=7;
    //设置下一个处理器对象
    private LeaveHandler nextHandler;

    public Manager(LeaveHandler nextHandler) {
        this.nextHandler = nextHandler;
    }

    @Override
    public void handleRequest(LeaveRequest request) {
        if(request.getDays()<=MAX_DAYS_SUPERVISOR_CAN_APPROVE){
            System.out.println(request.getName()+" Approved by Manager.");
        }else if(nextHandler !=null){
            nextHandler.handleRequest(request);
        }else{
            System.out.println(request.getName()+" Denied by Manager.");
        }
    }
}

//总监类
class Director implements LeaveHandler{
    private static final int MAX_DAYS_SUPERVISOR_CAN_APPROVE=10;

    @Override
    public void handleRequest(LeaveRequest request) {
        if(request.getDays()<=MAX_DAYS_SUPERVISOR_CAN_APPROVE){
            System.out.println(request.getName()+" Approved by Director.");
        }else{
            System.out.println(request.getName()+" Denied by Director.");
        }
    }
}

8.5.7总结

  • 优点:每个处理者只负责处理与自己相关的请求,客户端不需要具体时哪个处理者处理请求
  • 总结:类似过滤器中的链式处理,一个请求不断地在链式中传入下一个处理者,直到有一个处理者能处理该请求
  • 场景:适用于一个请求会被多个处理者进行处理,并且整条责任链模式中会有合适的处理者来处理请求
相关推荐
零千叶9 分钟前
【面试】AI大模型应用原理面试题
java·设计模式·面试
坐吃山猪5 小时前
SpringBoot01-配置文件
java·开发语言
我叫汪枫5 小时前
《Java餐厅的待客之道:BIO, NIO, AIO三种服务模式的进化》
java·开发语言·nio
yaoxtao5 小时前
java.nio.file.InvalidPathException异常
java·linux·ubuntu
Swift社区7 小时前
从 JDK 1.8 切换到 JDK 21 时遇到 NoProviderFoundException 该如何解决?
java·开发语言
DKPT7 小时前
JVM中如何调优新生代和老生代?
java·jvm·笔记·学习·spring
phltxy7 小时前
JVM——Java虚拟机学习
java·jvm·学习
seabirdssss9 小时前
使用Spring Boot DevTools快速重启功能
java·spring boot·后端
喂完待续9 小时前
【序列晋升】29 Spring Cloud Task 微服务架构下的轻量级任务调度框架
java·spring·spring cloud·云原生·架构·big data·序列晋升