likes
comments
collection
share

设计模式Java实现-责任链模式

作者站长头像
站长
· 阅读数 4

✨这里是第七人格的博客✨小七,欢迎您的到来~✨

🍅系列专栏:设计模式🍅

✈️本篇内容: 责任链模式✈️

🍱 本篇收录完整代码地址:gitee.com/diqirenge/d… 🍱

楔子

小七刚入行的时候,有一个业务需求需要根据不同的条件,进行不同的层级审核,最多要进行7级审核^_^,让小七至今都记忆犹新。因为当时工期紧张,小七和伙伴们直接就上了if-else大法。现在想一想其实可以做的设计有很多,比如引入流程引擎,或者使用责任链模式编写代码都可以。

设计模式Java实现-责任链模式

需求背景

现在有三级审核,需要根据时间段的不同设置不同的审核策略。

1、每月1-10号只需要三级审批;

2、每月11-20号,需要二级审批 + 三级审批;

3、每月21号及以后,需要一级审批+二级审批 + 三级审批;

要求不能引入流程引擎等框架,只能使用原生Java实现。

分析设计

根据需求我们可以将审核的全流程看做是一个链路,而具体是哪几级审核可以看做是链路上的节点,或者是子链路,我们要想办法将这些链路连接起来,参考以前学过的建造者模式,我们可以考虑抽象一个类,里面提供一个方法,传入自己并且返回自己

public abstract class AuditChain{
	private AuditChain next;
	public AuditChain addChain(AuditChain next) {
    	this.next = next;
    	return this;
	}
}

再提供一个方法,移动链路,以便执行每个子链路自己的业务

public AuditChain next() {
    return next;
}

这样基础的抽象类框架就搭建好了。再往里面填充我们的业务方法,延迟到子类实现就可以了。

UML图

根据分析设计,我们可以先画一个简单的UML图,后面通过UML图编码

设计模式Java实现-责任链模式

模块名称

responsibilitychain

模块地址

gitee.com/diqirenge/d…

模块描述

责任链模式代码示例

代码实现

1、编写接口

提供两个方法

①、获取下一个链路的方法

②、添加下一个链路的方法

/**
 * 链路处理接口
 * 关注公众号【奔跑的码畜】,一起进步不迷路
 *
 * @author 第七人格
 * @date 2024/01/02
 */
public interface Handler {
    /**
     * 获取下一个链路的方法
     *
     * @return {@link AuditChain}
     */
    AuditChain next();

    /**
     * 添加下一个链路的方法
     *
     * @param next 下一个链路
     * @return {@link AuditChain}
     */
    AuditChain addChain(AuditChain next);
}

2、编写抽象类,实现Handler接口

关键点在于:

①该类包含一个指向下一个处理器的引用private AuditChain next;

②定义一个处理方法addChain

public AuditChain addChain(AuditChain next) {
    this.next = next;
    return this;
}
/**
 * 审核链抽象类
 * 关注公众号【奔跑的码畜】,一起进步不迷路
 *
 * @author 第七人格
 * @date 2024/01/02
 */
public abstract class AuditChain implements Handler {

    protected String auditorId;
    protected String auditorName;
    private AuditChain next;

    public static int getDayOfMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.DAY_OF_MONTH);
    }

    public AuditChain(String auditorId, String auditorName) {
        this.auditorId = auditorId;
        this.auditorName = auditorName;
    }

    public AuditChain next() {
        return next;
    }

    public AuditChain addChain(AuditChain next) {
        this.next = next;
        return this;
    }

    public abstract void audit(String orderId, Date auditDate);

}

3、编写具体实现类

一级审核

/**
 * 链路:一级审核
 * 大于等于21号,才需要一级审核
 * 关注公众号【奔跑的码畜】,一起进步不迷路
 *
 * @author 第七人格
 * @date 2024/01/02
 */
public class Level1Chain extends AuditChain {

    public Level1Chain(String auditorId, String auditorName) {
        super(auditorId, auditorName);
    }

    public void audit(String orderId, Date auditDate) {
        if (21 <= AuditChain.getDayOfMonth(auditDate)) {
            System.out.println("====>一级负责人:" + auditorName + " 审核通过");
        }
        AuditChain next = super.next();
        if (next == null) {
            System.out.println("====>未找到下级审核人,流程结束");
        } else {
            next.audit(orderId, auditDate);
        }
    }

}

二级审核

/**
 * 链路:二级审核
 * 大于等于11号,才需要二级审核
 * 关注公众号【奔跑的码畜】,一起进步不迷路
 *
 * @author 第七人格
 * @date 2024/01/02
 */
public class Level2Chain extends AuditChain {

    public Level2Chain(String auditorId, String auditorName) {
        super(auditorId, auditorName);
    }

    public void audit(String orderId, Date auditDate) {
        if (11 <= AuditChain.getDayOfMonth(auditDate)) {
            System.out.println("====>二级负责人:" + auditorName + " 审核通过");
        }
        AuditChain next = super.next();
        if (next == null) {
            System.out.println("====>未找到下级审核人,流程结束");
        } else {
            next.audit(orderId, auditDate);
        }
    }

}

三级审核

/**
 * 链路:三级审核、
 * 三级审核不能跳过
 * 关注公众号【奔跑的码畜】,一起进步不迷路
 *
 * @author 第七人格
 * @date 2024/01/02
 */
public class Level3Chain extends AuditChain {

    public Level3Chain(String auditorId, String auditorName) {
        super(auditorId, auditorName);
    }

    public void audit(String orderId, Date auditDate) {
        System.out.println("====>三级负责人:" + auditorName + " 审核通过");
        AuditChain next = super.next();
        if (next == null) {
            System.out.println("====>未找到下级审核人,流程结束");
        } else {
            next.audit(orderId, auditDate);
        }
    }

}

4、编写测试类

/**
 * 测试责任链模式
 * 关注公众号【奔跑的码畜】,一起进步不迷路
 *
 * @author 第七人格
 * @date 2024/01/02
 */
public class ChainTest {

    @Test
    public void testAuditChain() {
        AuditChain auditChain = new Level3Chain("10086", "经办人小王")
                        .addChain(new Level2Chain("002", "李科")
                        .addChain(new Level1Chain("001", "张处")));

        System.out.println("\n====>测试1-10号的审批流程");
        auditChain.audit("orderId0001", new Date("2024/10/01 22:22:22"));

        System.out.println("\n====>测试11-20号的审批流程");
        auditChain.audit("orderId0002", new Date("2024/10/11 22:22:22"));

        System.out.println("\n====>测试20号后的审批流程");
        auditChain.audit("orderId0003", new Date("2024/10/22 22:22:22"));
    }

}

4、测试结果

====>测试1-10号的审批流程

====>三级负责人:经办人小王 审核通过

====>未找到下级审核人,流程结束

====>测试11-20号的审批流程

====>三级负责人:经办人小王 审核通过

====>二级负责人:李科 审核通过

====>未找到下级审核人,流程结束

====>测试20号后的审批流程

====>三级负责人:经办人小王 审核通过

====>二级负责人:李科 审核通过

====>一级负责人:张处 审核通过

====>未找到下级审核人,流程结束

实现要点

模板模式实现要点如下:

  1. 定义一个抽象处理器类,该类包含一个指向下一个处理器的引用,并定义一个处理方法。

    例子中为:抽象处理器类-AuditChain,引用next,处理方法addChain。

  2. 创建具体的处理器类,每个处理器类都继承自抽象处理器类,并实现处理方法。在处理方法中,首先判断当前处理器是否可以处理请求,如果可以则处理请求,否则将请求传递给下一个处理器。

    例子中为:Level1Chain、Level2Chain、Level3Chain的audit方法。

  3. 客户端代码创建一个处理器链,并将请求从链的一端传递到另一端。

    例子中为:

    AuditChain auditChain = new Level3Chain("10086", "经办人小王")
            .addChain(new Level2Chain("002", "李科")
                    .addChain(new Level1Chain("001", "张处")));
    

总结

责任链模式是一种行为型设计模式,它旨在将请求的发送者和接收者分离,使多个处理对象都有可能接收并处理请求。

转载自:https://juejin.cn/post/7331579180997574682
评论
请登录