专栏首页JimoerJava设计模式学习记录-责任链模式

Java设计模式学习记录-责任链模式

前言

 已经把五个创建型设计模式和七个结构型设计模式介绍完了,从这篇开始要介绍行为型设计模式了,第一个要介绍的行为型设计模式就是责任链模式(又称职责链模式)。

责任链模式

概念介绍

责任链模式是为了避免请求的发送者和接收者之间的耦合关系,使多个接收对象都有机会处理请求。将这些对象练成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。当然责任链中也有可能没有可以处理该请求的对象,这种情况是允许发生的。

举例

还是以前的规律,先举出具体的代码例子,然后再分析。拿前阵子在我老东家发生的一件事情来说,同事小王要结婚了,所以要请假回家筹备婚礼,但是公司有明确的规章制度,请假需要提前申请,并且每一级的领导能够审批的假期天数也不一样,部门经理可以审批12天的假期,技术总监能够审批3到5天的假期,大于5天的就要找CEO审批了,如果CEO审批通过了才可以休息5天以上的假期,小王筹备婚礼和渡蜜月总共要请10个工作日的假期。

用代码来实现这个过程就是下面?这个样子的。

先创建请假条类

/**
 * 请假条
 */
@Data
@AllArgsConstructor
public class Leave {

    /* 部门 */
    private String department;
    /* 员工名称 */
    private String name;
    /* 请假天数 */
    private double days;
    /* 请假事由 */
    private String cause;

}

然后创建审批人的抽象类

/**
 * 审批人
 */
public abstract class Approver {

    /* 审批人名称 */
    String name;
    /* 下一个审批人 */
    Approver nextApprover;

    public Approver(String name){
        this.name = name;
    }

    /**
     * 设置下一个审批人
     * @param approver
     */
    public void setNextApprover(Approver approver){
        this.nextApprover = approver;
    }

    /**
     * 审批
     * @param leave
     */
    public abstract void approval(Leave leave);

}

部门经理

/**
 * 部门经理
 */
public class Manager extends Approver {

    /**
     * 设置名称
     * @param name 领导名称
     */
    public Manager(String name) {
        super(name);
    }

    /**
     * 审批
     * @param leave 请假条
     */
    @Override
    public void approval(Leave leave) {

        if(leave.getDays()<3){
            System.out.println("请假小于3天,算临时休息,批准了。");
            System.out.println("部门经理审批通过---------审批流程over。");
        }else{
            if(Objects.nonNull(nextApprover)){
                System.out.println("部门经理批准不了这么多天的假期,需要上级审批。");
                this.nextApprover.approval(leave);
            }else{
                System.out.println(name+"的领导不在,等着吧。");
            }
        }

    }


}

技术总监

/**
 * 技术总监
 */
public class TechnicalDirector extends Approver {

    /**
     * 设置名称
     * @param name 领导名称
     */
    public TechnicalDirector(String name) {
        super(name);
    }

    /**
     * 审批
     * @param leave 请假条
     */
    @Override
    public void approval(Leave leave) {
        if(leave.getDays()<5){
            System.out.println("请假小于5天,算有事休息,批准了。");
            System.out.println("技术总监审批通过---------审批流程over。");
        }else{
            if(Objects.nonNull(nextApprover)){
                System.out.println("技术总监批准不了这么多天的假期,需要上级审批。");
                this.nextApprover.approval(leave);
            }else{
                System.out.println(name+"的领导不在,等着吧。");
            }
        }
    }
}

CEO

/**
 * CEO
 */
public class CEO extends Approver {

    /**
     * 设置名称
     * @param name 领导名称
     */
    public CEO(String name) {
        super(name);
    }

    /**
     * 审批
     * @param leave 请假条
     */
    @Override
    public void approval(Leave leave) {

        if(leave.getDays()>5&&leave.getDays()<=10){
            System.out.println("情况特殊,批准了。");
            System.out.println("CEO审批通过---------审批流程over。");
        }else{
            System.out.println(name+"说请假的时间太长了不批,最好别一次性请这么久。");
        }

    }
}

测试类

public class Client {

    public static void main(String[] args) {

        //写请假条
        Leave leave = new Leave("技术部","小王",6.0,"结婚");



        //创建审批节点
        Approver zhangge = new Manager("张哥");
        Approver laozhao = new TechnicalDirector("老赵");
        Approver lizong = new CEO("李总");

        //将审批节点串起来
        zhangge.setNextApprover(laozhao);
        laozhao.setNextApprover(lizong);

        //开始审批
        zhangge.approval(leave);
    }

}

运行结果

部门经理批准不了这么多天的假期,需要上级审批。
技术总监批准不了这么多天的假期,需要上级审批。
情况特殊,批准了。
CEO审批通过---------审批流程over。

通过运行结果,我们可以看出来,当请假天数为10天时,部门经理和技术总监都已经处理不了了,然后抛给了CEO,通过CEO特批小王的婚假请求才算了审批完成。这个例子就是用到了我们今天说的责任链模式,下面继续分析责任链模式。

责任链模式分析

责任链的结构图

主要涉及到的角色

抽象处理者(Handler)角色:抽象处理者用于定义出一个处理请求的接口,如果需要,接口可以定义出一个方法,以返回对下一个处理对象的引用。上面例子中的Approver就是代表的这个角色。

具体处理者(ConcreteHandler)角色:处理接到的请求,可以选择将请求处理掉,或者将请求传递给下家。上面的例子中的Manager和TechnicalDirector以及CEO就是代表的这个角色。

责任链模式总结

纯的责任链模式和不纯的责任链模式

  • 纯的责任链模式要求一个具体的处理者对象只能在两个行为中选择一个:一个是承担责任;二是把责任推给下家。不允许出现某一个具体处理者对象在承担了一部分责任后又把责任向下传的情况。在一个纯的责任链中,一个请求必须被某一个处理者对象所接受。
  • 不纯的责任链模式中允许某个请求被一个具体处理者部分处理后再向下传递,或者一个具体处理者处理完某请求后其后继处理者可以继续处理该请求,而且一个请求可以最终不被任何处理者对象所接收。例如JavaScript中的事件冒泡。

责任链模式的优点

1、请求不需要指出被哪个对象处理了,这样的效果是请求者和接收者之间的解耦,而且链中的对象也不需要清楚其他链的结构,也降低了耦合。

2、请求处理对象仅需要维护一个指向其后继者的的引用,而不需要维护所有的处理对象,简化了对象之间的相互连接。

3、在给对象分派职责时,职责链可以给我们更多的灵活性,可以通过在运行时对该链进行动态的增加或修改来增加或改变处理一个请求的职责。

4、新增一个请求处理对象,不需要改动现有代码,只需要重新设置连接即可,符合“开闭原则”。

责任链模式的缺点

1、如果一个请求没有明确的接收者,那么就不能保证它一定会被处理,该请求可能一直到链的末端都得不到处理;一个请求也可能因职责链没有被正确配置而得不到处理。

2、 对于比较长的职责链,请求的处理可能涉及到多个处理对象,不仅增加了代码的复杂性并且系统性能也将受到一定影响,而且在进行代码调试时不太方便。

3、若建链不当,可能会造成循环调用,将导致系统陷入死循环。

适用场景

1、有多个对象可以处理同一个请求,具体哪个对象处理该请求待运行时刻再确定,客户端只需将请求提交到链上,而无须关心请求的处理对象是谁以及它是如何处理的。

2、在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。

3、可动态指定一组对象处理请求,客户端可以动态创建职责链来处理请求,还可以改变链中处理者之间的先后次序。

其实在我们日常开发中也会有适用到责任链模式的场景,try/catch、servlet(各个servelt互相调用)、以及filter等

想了解更多的设计模式请查看Java设计模式学习记录-GoF设计模式概述

现在是不是行业不景气呢?怎么最近连面试机会都少了?

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Java设计模式学习记录-简单工厂模式、工厂方法模式

    之前介绍了设计模式的原则和分类等概述。今天开启设计模式的学习,首先要介绍的就是工厂模式,在介绍工厂模式前会先介绍一下简单工厂模式,这样由浅入深来介绍。

    纪莫
  • Java设计模式学习记录-组合模式

    今天要介绍的设计模式是组合模式,组合模式也是结构型设计模式的一种,它主要体现了整体与部分的诶关系,其典型的应用就是树形结构。组合是一组对象,其中的对象可能包含一...

    纪莫
  • java设计模式之策略模式

    纪莫
  • mysql 多表关联查询 实现 全文匹配的 模糊搜索接口 SQLmysql 多表关联查询 实现 全文匹配的 模糊搜索接口 SQL

    在mysql中,有时我们在做数据库查询时,需要得到某字段中包含某个值的记录,但是它也不是用like能解决的,使用like可能查到我们不想要的记录,它比like更...

    一个会写诗的程序员
  • 【EJB学习笔记】——实体Bean

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huyuyang6688/article/...

    DannyHoo
  • Oozie分布式任务的工作流——Spark篇

    Spark是现在应用最广泛的分布式计算框架,oozie支持在它的调度中执行spark。在我的日常工作中,一部分工作就是基于oozie维护好每天的spark离线任...

    用户1154259
  • QHD DDIC is implemented via HANA

    版权声明:本文为博主汪子熙原创文章,未经博主允许不得转载。 https://jerry.bl...

    Jerry Wang
  • SpringDataJPA笔记(13)-Union查询

    在JPA中,对Union查询可以通过两种方式,一种是通过Inheritance的注解来实现,一种是通过子查询来实现,个人觉得子查询的方式更加灵活一点

    yingzi_code
  • Spring MVC浅入浅出——不吹牛逼不装逼

    上文书说了Spring相关的知识,对Spring来了个浅入浅出,大家应该了解到,Spring在三层架构中主做Service层,那还有Web层,也就是Contro...

    泰斗贤若如
  • Autowired注解

    package com.how2java.pojo; import org.springframework.beans.factory.annotation...

    互联网金融打杂

扫码关注云+社区

领取腾讯云代金券