【设计模式-4.3】行为型——责任链模式

说明:本文介绍设计模式中行为型设计模式中的,责任链模式;

审批流程

责任链模式属于行为型设计模式,关注于对象的行为。责任链模式非常典型的案例,就是审批流程的实现。如一个报销单的审批流程,根据报销单金额大小,需要不同的职位领导审批,金额越大,审批人的职务越高,如下:

代码如下:

(Staff,财务专员,审批金额不超过5000)

java 复制代码
/**
 * 财务专员
 */
public class Staff {

    private String name;

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

    /**
     * 审批
     * @param amount 金额
     * @return 是否通过
     */
    public boolean approve(double amount) {
        if (amount <= 5000) {
            System.out.println(name + "审批通过");
            return true;
        } else {
            System.out.println("驳回申请。【" + name + "】");
            return false;
        }
    }

    public String getName() {
        return name;
    }
}

(Manager,财务经理,审批金额不超过1w)

java 复制代码
/**
 * 财务经理
 */
public class Manager {

    private String name;

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

    /**
     * 审批
     * @param amount 金额
     * @return 是否通过
     */
    public boolean approve(double amount) {
        if (amount <= 10000) {
            System.out.println(name + "审批通过");
            return true;
        } else {
            System.out.println("驳回申请。【" + name + "】");
            return false;
        }
    }

    public String getName() {
        return name;
    }
}

(CFO,财务总监,审批金额不超过10w,否则直接找Boss)

java 复制代码
/**
 * 财务总监
 */
public class CFO {

    private String name;

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

    /**
     * 审批
     * @param amount 金额
     * @return 是否通过
     */
    public boolean approve(double amount) {
        if (amount <= 100000) {
            System.out.println(name + "审批通过");
            return true;
        } else {
            System.out.println("驳回申请。【" + name + "】");
            return false;
        }
    }

    public String getName() {
        return name;
    }
}

(Client,客户端,审批金额5000)

java 复制代码
/**
 * 客户端
 */
public class Client {
    public static void main(String[] args) {
        int amount = 8000;

        Staff staff = new Staff("财务专员");
        Manager manager = new Manager("财务经理");
        CFO cfo = new CFO("财务总监");

        if (!staff.approve(amount)) {
            if (!manager.approve(amount)) {
                if (!cfo.approve(amount)) {
                    System.out.println("找Boss");
                }
            }
        }
    }
}

(在财务经理这里审批通过)

通过上面的代码实现,可以看到客户端有多层的if判断,代码臃肿,不够灵活。

我们可以考虑将审批报销流程的各层人员抽象出来,成一个审批人,然后再在该类中再注入一个审批人为上级审批人。另外,创建一个抽象的审批方法,让其他审核人职务继承这个审批人类,实现其审批方法。方法内判断当前审批金额,该审核人职务不能审核其金额时,交给上级审批人审核。

如下:

(Approver,审批人抽象类,有审批人、下一个审批人,抽象审批方法)

java 复制代码
/**
 * 审批人
 */
public abstract class Approver {

    /**
     * 审批人姓名
     */
    protected String name;

    /**
     * 下一个审批人
     */
    protected Approver nextApprover;

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

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

    /**
     * 审批
     * @param amount
     */
    public abstract void approve(int amount);
}

(Staff,财务专员,审批金额不大于5000,否则交给下一位审批人审批)

java 复制代码
/**
 * 财务专员
 */
public class Staff extends Approver{

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

    @Override
    public void approve(int amount) {
        if (amount <= 5000) {
            System.out.println("审批通过。【" + name + "】");
        } else {
            System.out.println("金额太大,无法审批,交由上级处理。【" + name + "】");
            this.nextApprover.approve(amount);
        }
    }
}

(Manager,财务经理,审批金额不大于1w,否则交给下一位审批人审批)

java 复制代码
/**
 * 财务经理
 */
public class Manager extends Approver{

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

    @Override
    public void approve(int amount) {
        if (amount <= 10000) {
            System.out.println("审批通过。【" + name + "】");
        } else {
            System.out.println("金额太大,无法审批,交由上级处理。【" + name + "】");
            this.nextApprover.approve(amount);
        }
    }
}

(CFO,财务总监,审批金额不大于10w,否则找老板处理)

java 复制代码
/**
 * 财务总监
 */
public class CFO extends Approver{

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

    @Override
    public void approve(int amount) {
        if (amount <= 100000) {
            System.out.println("审批通过。【" + name + "】");
        } else {
            System.out.println("金额太大,无法审批,请找老板处理。【" + name + "】");
        }
    }
}

(Client,客户端)

java 复制代码
/**
 * 客户端
 */
public class Client {
    public static void main(String[] args) {
        // 审批金额
        int amount = 200000;

        // 审批人
        Staff staff = new Staff("财务专员");
        Manager manager = new Manager("财务经理");
        CFO cfo = new CFO("财务总监");

        // 设置下一个审批人
        manager.setNextApprover(cfo);
        staff.setNextApprover(manager);

        // 审批
        staff.approve(amount);
    }
}

执行结果,因为审批金额为20w,需要找老板处理;

或者使用链式编程,直接用一行代码搞定;

java 复制代码
/**
 * 客户端
 */
public class Client {
    public static void main(String[] args) {
        // 审批金额
        int amount = 200000;

        new Staff("财务专员").setNextApprover(new Manager("财务经理")).setNextApprover(new CFO("财务总监")).approve(amount);
    }
}

区别就在于使用链式编程,只会执行对应审批人内的if代码块;

以上是责任链模式的内容,责任链模式是很容易理解的设计模式,和我们日常生活非常紧密。但代码却不容易理解,在审批人对象里面再注入一个审批人对象,不容易想明白。

总结

本文参考《设计模式的艺术》、《秒懂设计模式》两书

相关推荐
_Evan_Yao7 小时前
Redis 缓存穿透、击穿、雪崩,一次讲清!
java·spring·mybatis
梓豪csd8 小时前
消息订阅中心:谁该收到哪条通知
java·开发语言·人工智能·低代码·自动化·1024程序员节
秋饼8 小时前
Spring AI 2.1 Message Parts 深度实战:推理签名回放与跨轮记忆持久化的源码级落地
java·ai·技术分享·后端开发
thefool1122668 小时前
TCP 1
java·1024程序员节
金銀銅鐵11 小时前
[Java] 用 GUI 展示 EnumSet 增减元素时的内部变化(下)
java·后端·ai编程
AI人工智能+电脑小能手11 小时前
一次请求打几个下游,这个Java并行任务工具类6个方法按序聚合
java·线程池·并发编程·1024程序员节·批量处理·并行任务
paopaokaka_luck13 小时前
心理咨询管理系统(WebSocket实时沟通、基于用户的协同过滤、 ECharts多维分析、 预约业务流程、预约校验与定时处理)
java·vue.js·spring boot·mysql·spring·echarts·1024程序员节
2301_322414280413 小时前
springboot农产品交易平台的设计与实现08055-计算机毕设 原创(免费领源码+部署教程+开发环境)
java·spring boot·redis·mysql·tomcat·maven·mybatis
考虑考虑14 小时前
JDK26的JEP 500属性
java·后端·java ee
LMT流氓兔14 小时前
第五单元——第十二课:把脚本整理成项目
java·数据库·python·langchain·1024程序员节