• 责任链模式auto-pipeline工具使用及源码解析


    背景

    ​ 设计模式责任链模式是一种类似于“击鼓传花”的模式,执行者对象拥有下一个对象的引用从而形式一条链,请求在这个链上传递。常见的如审批模式等。这里介绍一下 auto-pipeline 工具,该工具仅使用 @AutoPipeline 便可自动生责任链相关的系统代码,让开发者更专注于业务流程的开发。

    auto-pipeline 工具使用

    场景举例:申请人先填写申请单,然后交给领导审批,如果申请批准下来,领导会通知申请人审批通过,然后申请人去财务领取费用,如果没有批准下来,领导会通知申请人审批未通过,此事也就此作罢。不同级别的领导,对于审批的额度是不一样的,比如,项目经理只能审批500元以内的申请;部门经理可以审核任意额度的申请(这里为了测试,只有张三提的审批部门经理才会同意)。

    1)要生成 pipeline 的接口加上 @AutoPipeline 注解
    import com.foldright.auto.pipeline.AutoPipeline;
    
    // 先编译一下才会自动生成责任链相关类
    @AutoPipeline
    public interface Staff {
        String approve(String user, double fee);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    2)编写项目经理和部门经理业务类
    /**
     * 项目经理
     */
    public class ProjectManager implements StaffHandler {
    
        @Override
        public String approve(String user, double fee, StaffHandlerContext staffHandlerContext) {
            if (fee < 500) {
                //项目经理权限比较小,只能在500以内
                return "成功:项目经理同意【" + user + "】的聚餐费用,金额为" + fee + "元";
            } else {
                // 更高领导审批
                return staffHandlerContext.approve(user, fee);
            }
        }
    }
    
    /**
     * 部门经理
     */
    public class DeptManager implements StaffHandler {
        @Override
        public String approve(String user, double fee, StaffHandlerContext staffHandlerContext) {
            //为了测试,简单点,只同意张三的请求
            if ("张三".equals(user)) {
                return "成功:部门经理同意【" + user + "】的聚餐费用,金额为" + fee + "元";
            } else {
                //其他人一律不同意
                return "失败:部门经理不同意【" + user + "】的聚餐费用,金额为" + fee + "元";
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    3)测试用例
    public class Main {
    
        public static void main(String[] args) {
            Staff staffPipeline = new StaffPipeline()
                    .addLast(new ProjectManager())
                    .addLast(new DeptManager());
    
            // case 1:张三发起300元审批,项目经理同意
            String approveResult1 = staffPipeline.approve("张三", 300);
            System.out.println(approveResult1);
    
            // case 2:张三发起700元审批,项目经理无权审批,部门经理同意
            String approveResult2 = staffPipeline.approve("张三", 700);
            System.out.println(approveResult2);
    
            // case 3:李四发起700元审批,项目经理无权审批,部门经理不同意
            String approveResult3 = staffPipeline.approve("李四", 700);
            System.out.println(approveResult3);
    
        }
    }
    
    // output:
    成功:项目经理同意【张三】的聚餐费用,金额为300.0元
    成功:部门经理同意【张三】的聚餐费用,金额为700.0元
    失败:部门经理不同意【李四】的聚餐费用,金额为700.0
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    4)代码结构

    在这里插入图片描述

    auto-pipeline 源码解析

    在这里插入图片描述

    核心思路:StaffPipeline 类负责将 StaffHandler 封装成 DefaultStaffHandlerContext 并串联成链表,DefaultConfigSourceHandlerContext 持有 StaffHandler 对象的默认实现,另外 StaffHandlerContext 表示 Handler 的上下文,相比传统责任链,新增了获取全局Pipeline的能力。上面的 UML 可以清楚看出 auto-pipeline 的源码内部类结构,简单易理解。

  • 相关阅读:
    CSS之flex布局
    设计模式:原型模式
    光链路测试6271B光纤温度分布测试仪
    Vite探索:构建、启程、原理、CSS艺术与插件魔法
    并查集及其优化
    golang学习参考记录
    [静态时序分析简明教程(一)] 绪论
    C#的Console 类使用说明
    在Spring Boot中使用JTA实现对多数据源的事务管理
    108页6万字某小区施工组织设计方案
  • 原文地址:https://blog.csdn.net/zhuqiuhui/article/details/127599896