设计模式是什么鬼(责任链)

简介: 设计模式是什么鬼(责任链)

曾经有这么一些零散的功能节点,他们各自承担各自的义务,分工明确,各司其职。为了更高效,更完整地解决客户的问题,他们发扬团队精神,互相串联起来形成一个有序的责任传递链表,于是责任链模式诞生了。当然,它的结构也不一定非得是链表,甚至可以是树型分叉结构,这要根据业务场景看怎样去灵活运用,但其核心意义是为了处理某种连续的流程,并确保业务一定能走到相应的责任节点上并得到相应的处理。


image.png


说到这里想必大家已经想到了工作流吧?对,企事业单位中通常为了完成某项日常任务,通常要制定一些工作流程,按步骤拆分,并组织好各个环节中的逻辑关系及走向,这样才能更高效、更规范地完成任务。



image.png


根据以上流程图,我们来做一个最简单的例子。假设某公司针对出差报销业务制定审批流程,有三个审批角色分别是员工(1000元权限)、经理(5000元权限)、以及CEO(10000元权限),各审批人代码如下。


1public class Staff {
 2
 3    private String name;
 4
 5    public Staff(String name) {
 6        this.name = name;
 7    }
 8
 9    public boolean approve(int amount) {
10        if (amount <= 1000) {
11            System.out.println("审批通过。【员工:" + name + "】");
12            return true;
13        } else {
14            System.out.println("无权审批,请找上级。【员工:" + name + "】");
15            return false;
16        }
17    }
18
19}
1public class Manager {
 2
 3    private String name;
 4
 5    public Manager(String name) {
 6        this.name = name;
 7    }
 8
 9    public boolean approve(int amount) {
10        if (amount <= 5000) {
11            System.out.println("审批通过。【经理:" + name + "】");
12            return true;
13        } else {
14            System.out.println("无权审批,请找上级。【经理:" + name + "】");
15            return false;
16        }
17    }
18
19}
1public class CEO {
 2
 3    private String name;
 4
 5    public CEO(String name) {
 6        this.name = name;
 7    }
 8
 9    public boolean approve(int amount) {
10        if (amount <= 10000) {
11            System.out.println("审批通过。【CEO:" + name + "】");
12            return true;
13        } else {
14            System.out.println("驳回申请。【CEO:" + name + "】");
15            return false;
16        }
17    }
18
19}


好了,审批人们定义完毕,逻辑非常简单缜密,如果超过审批金额最大权限则打回去,开始写申请人客户端类。


1public class Client {
 2    public static void main(String[] args) {
 3        int amount = 10000;//出差花费10000元
 4        // 先找员工张飞审批
 5        Staff staff = new Staff("张飞");
 6        if (!staff.approve(amount)) {
 7            //被拒,找关二爷问问。
 8            Manager manager = new Manager("关羽");
 9            if (!manager.approve(amount)) {
10                //还是被拒,只能找老大了。
11                CEO ceo = new CEO("刘备");
12                ceo.approve(amount);
13            }
14        }
15        /***********************
16        无权审批,请找上级。【员工:张飞】
17        无权审批,请找上级。【经理:关羽】
18        审批通过。【CEO:刘备】
19        ***********************/
20    }
21}


功夫不负有心人,跑了三个地方找了三个人,一万元的大额报销单终于被大老板审批了。然而,大家有没有发现问题?我们走的审批流程好像有点过于复杂了,找这个不行那个不同意,跑来跑去的好像自己有点像是被踢皮球的感觉。此外,如果我们后期要优化完善此工作流程,或是添加新的审批角色进来,那就得不停地修改此处的逻辑,最终的修改结果会是?



image.png


乱了,全乱套了,我们终将被淹没在一堆复杂的审批流程中,跑断腿也找不到门路。这显然是违反设计模式原则的,我们必须进行重构。我们观察此类中的审批逻辑,这显然就是一个链式结构,审批人之间环环相扣,对于自己无法处理的申请,会像被踢皮球似的传给上级,直到某人解决此申请,对员工张飞来说,他只知道自己传球给关羽了,仅此而已。


进一步分析,审批人肯定是不同的角色,并且每个角色的审批逻辑会有区别,所以我们得把这些角色的审批逻辑分开来写,对每个角色的责任范围我们进行定义,我只懂自己怎么审批(责任),我处理不了的我递交给上层(链条),开始重构,先抽象出一个审批人类。


1public abstract class Approver {// 审批人抽象类
 2
 3    protected String name;// 抽象出审批人的姓名。
 4    protected Approver nextApprover;// 下一个审批人,更高级别领导。
 5
 6    public Approver(String name) {
 7        this.name = name;
 8    }
 9
10    protected Approver setNextApprover(Approver nextApprover) {
11        this.nextApprover = nextApprover;
12        return this.nextApprover;// 返回下个审批人,链式编程。
13    }
14
15    public abstract void approve(int amount);// 抽象审批方法由具体审批人子类实现
16}


注意第4行,审批人只认识自己的领导,所以会持有下一级领导的引用,同时第10行的代码用于把领导注入进来。第15行是我们的审批方法了,但每个角色审批逻辑会有区别,所以这里进行抽象,并由具体的审批角色子类去实现,先从员工看起。


1public class Staff extends Approver {
 2
 3    public Staff(String name) {
 4        super(name);
 5    }
 6
 7    @Override
 8    public void approve(int amount) {
 9        if (amount <= 1000) {
10            System.out.println("审批通过。【员工:" + name + "】");
11        } else {
12            System.out.println("无权审批,升级处理。【员工:" + name + "】");
13            this.nextApprover.approve(amount);
14        }
15    }
16
17}


很简单,员工类继承了审批角色类,第9行申明审批权限为1000元,重点在于第13行这里调用了自己上级领导的审批方法,显然这里是自己处理不了的申请单了。大同小异,再重构经理及CEO审批角色类。


1public class Manager extends Approver {
 2
 3    public Manager(String name) {
 4        super(name);
 5    }
 6
 7    @Override
 8    public void approve(int amount) {
 9        if (amount <= 5000) {
10            System.out.println("审批通过。【经理:" + name + "】");
11        } else {
12            System.out.println("无权审批,升级处理。【经理:" + name + "】");
13            this.nextApprover.approve(amount);
14        }
15    }
16
17}
1public class CEO extends Approver {
 2
 3    public CEO(String name) {
 4        super(name);
 5    }
 6
 7    @Override
 8    public void approve(int amount) {
 9        if (amount <= 10000) {
10            System.out.println("审批通过。【CEO:" + name + "】");
11        } else {
12            System.out.println("驳回申请。【CEO:" + name + "】");
13        }
14    }
15
16}


CEO类作为链条的尾巴,也就是最高级别,第12行的越权逻辑会最终拒绝申请单。很简单吧?我们生成一下这个链条,并从员工开始传递申请单。


1public class Client {
 2    public static void main(String[] args) {
 3        Approver flightJohn = new Staff("张飞");
 4        flightJohn.setNextApprover(new Manager("关羽")).setNextApprover(new CEO("刘备"));
 5
 6        //高层接触不到也没必要接触,直接找员工张飞审批。
 7        flightJohn.approve(1000);
 8        /***********************
 9        审批通过。【员工:张飞】
10        ***********************/
11
12        flightJohn.approve(4000);
13        /***********************
14        无权审批,升级处理。【员工:张飞】
15        审批通过。【经理:关羽】
16        ***********************/
17
18        flightJohn.approve(9000);
19        /***********************
20        无权审批,升级处理。【员工:张飞】
21        无权审批,升级处理。【经理:关羽】
22        审批通过。【CEO:刘备】
23        ***********************/
24
25        flightJohn.approve(88000);
26        /***********************
27        无权审批,升级处理。【员工:张飞】
28        无权审批,升级处理。【经理:关羽】
29        驳回申请。【CEO:刘备】
30        ***********************/
31    }
32}


这里注意第4行的代码对责任链进行构造(其实这里我们还可以交由工作流工厂去构造完成,读者可以自己实践练习),从员工开始一直到CEO结束。之后的业务就非常简单了,直接递单给员工张飞,审批流程便魔法般地启动了,审批单在这个责任链条上层层递交,最终给出结果。


至此,申请人与审批人实现了解耦,我们只需递单送给责任链即可,申请人不必再关心每个处理细节,只需交给接口人张飞处理就妥了。使用了责任链模式后的代码看起来非常简洁,各个角色的责任划分非常明确并且被分开定义到了每个角色类中,再把他们串起来去调用,一气呵成。后期如果再继续添加新的角色只需要添加新角色类并加入链条即可,链条的随意伸缩,灵活的可伸缩性,完美的扩展性。挂上这条钛合金项链,维护世界和平的责任就交给你了!



image.png


在实际应用中,我们切勿生搬硬套,还需根据实际需求场景进行灵活运用,就拿工业现代化生产线举例,这个其实也类似责任链模式,但不同之处在于其组装工作是必须经过每个组装节点处理的,从头到尾的全链处理而不能中途退出,读者朋友可以自己写代码练习,实践与思考要相结合并循环往复,二者都非常重要。

相关文章
|
17天前
|
设计模式 Java
常用设计模式(工厂方法,抽象工厂,责任链,装饰器模式)
有关设计模式的其他常用模式请参考 单例模式的实现 常见的设计模式(模板与方法,观察者模式,策略模式)
41 2
|
8天前
|
设计模式 安全 Java
设计模式之责任链 Chain Of Responsibility
设计模式之责任链 Chain Of Responsibility
22 1
|
17天前
|
设计模式 Java Spring
责任链设计模式详解
该内容主要介绍了如何使用Java实现责任链模式。
33 4
|
17天前
|
设计模式 算法 调度
行为型设计模式:模板设计模式/观察者设计模式/策略设计模式/责任链设计模式
行为型设计模式:模板设计模式/观察者设计模式/策略设计模式/责任链设计模式
35 0
|
设计模式 分布式计算 大数据
大数据开发基础的设计模式的责任链
当涉及大数据的开发时,设计模式是至关重要的。其中一种常见的设计模式是责任链模式,它可以有效地处理多个对象之间的请求。
70 0
|
设计模式 前端开发 数据安全/隐私保护
前端通用编程基础的设计模式之责任链
在前端开发中,我们常常需要处理一些复杂的业务逻辑,例如表单验证、权限控制等。这些业务逻辑可能需要经过多个步骤才能完成,每个步骤都需要进行具体的处理和判断。这时候就需要使用责任链模式来实现业务逻辑的流程化和扩展性。
107 0
|
设计模式 前端开发 JavaScript
前端通用编程基础的设计模式之责任链
在前端开发中,我们经常需要处理复杂的业务逻辑和数据流转。为了解决这些问题,设计模式中的责任链模式可以帮助我们快速地构建一个多级处理机制,从而使得代码更加简洁、可维护并且易于扩展。
82 0
|
设计模式
24种设计模式-责任链设计模式
24种设计模式-责任链设计模式
|
设计模式 前端开发 Java
|
设计模式 XML 存储
设计模式之责任链
设计模式之责任链
163 1
设计模式之责任链