行为篇-责任链模式


前言

责任链是由很多责任节点串联起来的一条任务链条,其中每一个责任节点都是一个业务处理环节。责任链模式(Chain of Responsibility)允许业务请求者将责任链视为一个整体并对其发起请求,而不必关心链条内部具体的业务逻辑与流程走向,也就是说,请求者不必关心具体是哪个节点起了作用,总之业务最终能得到相应的处理。在软件系统中,当一个业务需要经历一系列业务对象去处理时,我们可以把这些业务对象串联起来成为一条业务责任链,请求者可以直接通过访问业务责任链来完成业务的处理,最终实现请求者与响应者的解耦。


提示:以下是本篇文章正文内容,下面案例可供参考

一、简单的生产线

以最简单的责任链举例,汽车生产线的制造流程就使用了这种模式。首先我们进行劳动分工,将汽车零件的安装工作拆分并分配给各安装节点,责任明确划分;然后架构生产线,将安装节点组织起来,首尾相接,规划操作流程;最终,通过生产线的传递,汽车便从零件到成品得以量产,生产效率大大提升。

我们将汽车生产线从左至右分为3个功能节点,其中A节点负责组装车架、安装车轮;B节点负责安装发动机、油箱、传动轴等内部机件;C节点进行组装外壳、喷漆等操作,这样将产品逐级传递,每经过一个节点就完成一部分工作,最终完成产品交付。

二、工作流程拆分

生产线的例子其实相对机械、简单,我们来看一个带有一些逻辑的责任链:报销审批流程。公司为了更高效、安全规范地把控审核工作,通常会将整个审批工作过程按负责人或者工作职责进行拆分,并组织好各个环节中的逻辑关系及走向,最终形成标准化的审批流程。

审批流程需要依次通过财务专员、财务经理、财务总监的审批。如果申请金额在审批人的审批职权范围内则审批通过并终止流程,反之则会升级至更高层级的上级去继续审批,直至最终的财务总监,如果仍旧超出财务总监的审批金额则驳回申请,流程终止。

我们思考一下该如何设计这个审批流程,如果将业务逻辑写在一个类中去完成,还不至于太烦琐,但是如果需要进一步修改审批流程,我们就必须不断地更改这段逻辑代码,导致可扩展性、可维护性变差,完全谈不上任何设计。因此,我们有必要首先按角色对业务进行拆分,将不同的业务代码放在不同的角色类中,如此达到职权分拆的目的,可维护性也能得到提高。

1.业务实现

我们来做一个简单的实例。假设某公司的报销审批流程有3个审批角色,分别是财务专员(1000元审批权限)、财务经理(5000元审批权限)以及财务总监(10000元审批权限)。

//财务专员类
public class Staff {
    private String name;

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

    public boolean approve(int amount){
        if(amount <= 1000){
            System.out.println("审批通过。专员:" + name);
            return true;
        }else {
            System.out.println("无权审批,请找上级。专员:" + name);
            return false;
        }
    }
}

//财务经理类
public class Manager {
    private String name;

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

    public boolean approve(int amount){
        if(amount <= 5000){
            System.out.println("审批通过。经理:" + name);
            return true;
        }else {
            System.out.println("无权审批,请找上级。经理:" + name);
            return false;
        }
    }
}

//财务总监类
public class CFO {
    private String name;

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

    public boolean approve(int amount){
        if(amount <= 5000){
            System.out.println("审批通过。总监:" + name);
            return true;
        }else {
            System.out.println("驳回申请。总监:" + name);
            return false;
        }
    }
}

说明:

  1. 以财务总监类为例,定义了财务总监类CFO的审批方法approve()并接受要审批的金额,如果金额在10000元以内则审批通过,否则驳回此申请。3个审批角色的代码都比较类似,只要超过其审批金额的权限就驳回申请,反之则审批通过。

2.客户端类

public class Client {
    public static void main(String[] args) {
        int amount = 10000;//出差花费10000元
        Staff staff = new Staff("张飞");
        if(!staff.approve(amount)){
            Manager manager = new Manager("关羽");
            if(!manager.approve(amount)){
                CFO cfo = new CFO("刘备");
                cfo.approve(amount);
            }
        }
    }
}
输出结果:
无权审批,请找上级。专员:张飞
无权审批,请找上级。经理:关羽
驳回申请。总监:刘备

说明:

  1. 10000元的大额报销单终于被总监审批了。然而这种办事效率确实不敢恭维,申请人先找专员被升级处理,再找经理又被告知数额过大得去找总监,来来回回找了3个审批人处理,浪费了申请人的大量时间与精力。虽然事情是办理了,但申请人非常不满意,审批流程太过烦琐,总觉得有种被踢皮球的感觉。
  2. 如果我们后期为了优化和完善这个业务流程而添加新的审批角色,或者进一步增加更加复杂的逻辑,那么情况就会变得更糟。申请人不得不跟着学习这个流程,不停修改自己的申请逻辑,无形中增加了维护成本。

三、架构工作流

缺少架构的流程不是完备的工作流,否则申请人终将被淹没在一堆复杂的审批流程中。要完全解决申请人与审批人之间的矛盾,我们必须对现有代码进行重构。

1.审批人

经过观察代码中的审批流程逻辑,我们可以发现审批人的业务之间有环环相扣的关联,对于超出审批人职权范围的申请会传递给上级,直到解决问题为止。这种传递机制就需要我们搭建一个链式结构的工作流,这也是责任链模式的精髓之所在。基于这种思想,我们来重构审批人的代码

public abstract class Approver {

    protected String name;
    protected Approver nextApprover; //下一位审批人,更高级别的领导

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

    public Approver setNextApprover(Approver nextApprover) {
        this.nextApprover = nextApprover;
        return this.nextApprover; //返回下一位审批人,使其支持链式编程
    }

    //抽象审批方法由具体审批人子类实现
    public abstract void approve(int amount);
}

说明:

  1. 我们用抽象类来定义审批人。由于审批人在无权审批时需要传递业务给其上级领导,因此我们定义上级领导的引用nextApprover,与下一位审批人串联起来,同时将其注入。当然,每位审批人的角色不同,其审批逻辑也有所区别,所以我们对审批方法进行抽象,交由具体的子类审批角色去继承和实现。

2.审批角色

//财务专员类
public class Staff extends Approver{

    public Staff(String name) {
        super(name);
    }

    public void approve(int amount){
        if(amount <= 1000){
            System.out.println("审批通过。专员:" + name);
        }else {
            System.out.println("无权审批,请找上级。专员:" + name);
            this.nextApprover.approve(amount);
        }
    }
}

//财务经理类
public class Manager extends Approver{

    public Manager(String name) {
        super(name);
    }

    public void approve(int amount){
        if(amount <= 5000){
            System.out.println("审批通过。经理:" + name);
        }else {
            System.out.println("无权审批,请找上级。经理:" + name);
            this.nextApprover.approve(amount);
        }
    }
}

//财务总监类
public class CFO extends Approver{

    public CFO(String name) {
        super(name);
    }

    public void approve(int amount){
        if(amount <= 10000){
            System.out.println("审批通过。财务总监:" + name);
        }else {
            System.out.println("驳回申请。财务总监:" + name);
        }
    }
}

说明:

  1. 比较特殊的审批人是责任链末节点的财务总监类,如代码所示,最高职级的财务总监CFO的审批逻辑略有不同,当申请金额超出10000元后就再有下一个审批人了,所以此时就会驳回报销申请。

3.客户端类

一切就绪,是时候生成这条责任链了。

public class Client {
    public static void main(String[] args) {
        Approver staff = new Staff("张飞");
        staff.setNextApprover(new Manager("关羽")).setNextApprover(new CFO("刘备"));
        staff.approve(1000);
        staff.approve(4000);
        staff.approve(9000);
        staff.approve(188000);
    }
}
输出结果:
审批通过。专员:张飞
    
无权审批,请找上级。专员:张飞
审批通过。经理:关羽
    
无权审批,请找上级。专员:张飞
无权审批,请找上级。经理:关羽
审批通过。财务总监:刘备
    
无权审批,请找上级。专员:张飞
无权审批,请找上级。经理:关羽
驳回申请。财务总监:刘备

说明:

  1. 一开始我们构造了财务专员,接着组装了责任链由低到高逐级进行审批角色对象的注入,直至财务总监。申请人的业务办理流程就非常简单了,客户端直接面对的就是财务专员,只需将申请递交给他处理,接着审批流程奇迹般地启动了,业务在这个责任链上层层递交,直至完成。请从代码第9行开始查看各种不同金额的审批场景对应的办理流程,从输出看出达到了工作流的预期运行结果。

总结

提示:这里对文章进行总结:

  1. 至此,以责任链模式为基础架构的工作流搭建完成,各审批角色只需要定义其职权范围内的工作,再依靠高层抽象实现角色责任的链式结构,审批逻辑得以拆分、串联,让业务申请在责任链上逐级传递。

  2. 责任链模式的各角色定义如下。

  • Handler(业务处理者):所有业务处理节点的顶层抽象,定义了抽象业务处理方法handle()并留给子类实现,其实体方法setSuccessor()(注入继任者)则用于责任链的构建。对应本章例程中的审批人Approver。
  • ConcreteHandler1、ConcreteHandler2……(业务处理者实现类):实际业务处理的实现类,可以有任意多个,每个都实现了handle()方法以处理自己职权范围内的业务,职权范围之外的事则传递给下一位继任者(另一个业务处理者)。对应本章例程中的财务专员类Staff、财务经理类Manager、财务总监类CFO。
  • Client(客户端):业务申请人,只需对业务链条的第一个入口节点发起请求即可得到最终响应。
  1. 对责任链模式的应用让我们一劳永逸,之后我们便可以泰然自若地应对业务需求的变更,方便地对业务链条进行拆分、重组,以及对单独节点的增、删、改。结构松散的业务处理节点让系统具备更加灵活的可伸缩性、可扩展性。责任链模式让申请方与处理方解耦,申请人可以彻底从业务细节中解脱出来,无论多么复杂的审批流程,都只需要简单的等待,让业务在责任链上飞一会儿。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhixuChen200

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值