面试官:什么是责任链模式?

前言

大家好,我是程序员大聪明,上一期介绍了单例模式,感兴趣的小伙伴可以再去翻看之前的分享。接下来给大家介绍另一个在工作中常用的设计模式:责任链模式

定义

什么是责任链?它有什么特点?

责任链模式是一种行为型设计模式。在责任链模式里,每个对象都持有下一个要处理对象的引用,从而形成一条链。当客户端发起请求时,请求将会在这条链上传递,每一个对象都有机会去处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。

具体的流程如下:

在这里插入图片描述

应用场景

  1. OA审批流(比如发起休假流程,根据休假的天数决定当前流程需要流向哪几位部门领导审批)
  2. Filter过滤器(比如注册账号流程,需先后经过账号、密码等合法性校验)

实现方式

  • 需求背景

请你设计一个员工休假审批流程,当员工的休假天数<=1时,由直接领导审批,休假天数<=2时,分别由直接领导、一级部门领导审批,休假天数>=3时,分别由直接领导、一级部门领导、分管领导审批。

先构造一个请求体RequestParam,包含申请人的姓名以及休假的天数。

/**
 * 审批请求体
 * @author coder_smart
 */
@Getter
@Setter
public class RequestParam {

    // 申请人
    private String name;

    // 休假时间
    private int time;

    public RequestParam(String name, int time) {
        this.name = name;
        this.time = time;
    }

    public RequestParam() {}
}

在没有使用任何奇淫技巧的情况下,你可能会这么写代码。

public class Main{
    
    
    public static void main(String[] args) {
    
    
        // 初始化请求参数
        RequestParam requestParam = new RequestParam("张三", 3);

        if (requestParam.getTime() >= 1) {
    
    
            // 直接领导审批
            if (requestParam.getTime() >= 2) {
    
    
                // 一级部门领导审批
                if (requestParam.getTime() >= 3) {
    
    
                    // 分管领导审批
                }
            }
        }
    }
}

可以很明显的看出,每个处理逻辑都有一个if分支包围着,在业务需求不复杂或者处理节点数不多的情况下,这样写是完全没有问题的,但是如果产品经理提了个小意见,当休假天数等于0.5时,由HR审批,当休假天数等于2.5时,由二级部门领导审批,这时候你就不得不改动嵌套的if分支代码,大大的降低了代码的可读性和扩展性。

  • 采用责任链模式进行改造
/**
 * 抽象审批类
 * @author coder_smart
 */
public abstract class AuditHandler {
    
    
    // 下一个处理节点
    protected AuditHandler nextAuditHandler;

    // 设置下一个处理节点
    public void setNextAuditHandler(AuditHandler nextAuditHandler) {
    
    
        this.nextAuditHandler = nextAuditHandler;
    }

    // 抽象方法,子类实现各自处理的逻辑
    public abstract void audit(RequestParam requestParam);
}

抽象审批类AuditHandler,包含下一个处理者的引用nextAuditHandler,通过setNextAuditHandler方法进行注入,从而形成一条链,抽象audit方法,由各个处理者的实现类去实现各自的审批逻辑。

/**
 * 直接领导审批处理类
 * @author coder_smart
 */
public class FirstLeaderAuditHandler extends AuditHandler{
    
    

    @Override
    public void audit(RequestParam requestParam) {
    
    
        System.out.print("start");
        System.out.print("---> 直接领导审批 ");
        if (requestParam.getTime() <= 1) {
    
    
            // do Something
            System.out.print("---> end");
            return;
        }
        nextAuditHandler.audit(requestParam);
    }
}
/**
 * 一级部门领导审批处理类
 * @author coder_smart
 */
public class SecondLeaderAuditHandler extends AuditHandler{
    
    

    @Override
    public void audit(RequestParam requestParam) {
    
    
        System.out.print("---> 一级部门领导审批 ");
        if (requestParam.getTime() <= 2) {
    
    
            // do Something
            System.out.print("---> end");
            return;
        }
        nextAuditHandler.audit(requestParam);
    }
}
/**
 * 分管领导审批处理类
 * @author coder_smart
 */
public class ThirdLeaderAuditHandler extends AuditHandler{
    
    

    @Override
    public void audit(RequestParam requestParam) {
    
    
        // do Something
        System.out.print("---> 分管部门领导审批 ");
        System.out.print("---> end");
        return;
    }
}
/**
 * 客户端
 *
 * @author coder_smart
 */
public class Main {
    
    
    public static void main(String[] args) {
    
    

        // 初始化请求参数
        // RequestParam requestParam = new RequestParam("张三", 1);
        // RequestParam requestParam = new RequestParam("张三", 2);
        RequestParam requestParam = new RequestParam("张三", 3);

        // 构建各处理节点对象
        AuditHandler firstLeaderHandler = new FirstLeaderAuditHandler();
        AuditHandler secondLeaderHandler = new SecondLeaderAuditHandler();
        AuditHandler thirdLeaderHandler = new ThirdLeaderAuditHandler();

        // 组装成责任链
        firstLeaderHandler.setNextAuditHandler(secondLeaderHandler);
        secondLeaderHandler.setNextAuditHandler(thirdLeaderHandler);

        // 开始审批
        firstLeaderHandler.audit(requestParam);
        
        // console log
        // time=1, start---> 直接领导审批 ---> end
        // time=2, start---> 直接领导审批 ---> 一级部门领导审批 ---> end
        // time=3, start---> 直接领导审批 ---> 一级部门领导审批 ---> 分管部门领导审批 ---> end
    }
}

总结

在工作过程中,各位小伙伴千万不要为了炫技,把设计模式在自己的业务代码通通用个遍,适合当前业务的模式,才是好的设计模式。

设计模式的种类繁多,责任链是我觉得最有意思的一种,非常值得各位小伙伴学习。

如果本文对你有所帮助的话,麻烦一键三连,点赞收藏在看

想更深入的了解设计模式原理以及相关面试题,更多详细资料请见:https://cloud.fynote.com/share/d/qinfK72

猜你喜欢

转载自blog.csdn.net/qq_41917138/article/details/126191637