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

前言

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

责任链模式

概念介绍

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

举例

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

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

先建立请假条类ide

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

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

}

而后建立审批人的抽象类post

/**
 * 审批人
 */
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+"说请假的时间太长了不批,最好别一次性请这么久。");
        }

    }
}

测试类this

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中的事件冒泡。

责任链模式的优势

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

二、请求处理对象仅须要维护一个指向其后继者的的引用,而不须要维护全部的处理对象,简化了对象之间的相互链接。

三、在给对象分派职责时,职责链能够给咱们更多的灵活性,能够经过在运行时对该链进行动态的增长或修改来增长或改变处理一个请求的职责。

四、新增一个请求处理对象,不须要改动现有代码,只须要从新设置链接便可,符合“开闭原则”。

责任链模式的缺点

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

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

三、若建链不当,可能会形成循环调用,将致使系统陷入死循环。

适用场景

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

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

三、可动态指定一组对象处理请求,客户端能够动态建立职责链来处理请求,还能够改变链中处理者之间的前后次序。

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

 

 

 

 

 

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

 

 

 

 

 

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

相关文章
相关标签/搜索