✨这里是第七人格的博客✨小七,欢迎您的到来~✨
🍅系列专栏:设计模式🍅
✈️本篇内容: 责任链模式✈️
🍱 本篇收录完整代码地址:gitee.com/diqirenge/d... 🍱
楔子
小七刚入行的时候,有一个业务需求需要根据不同的条件,进行不同的层级审核,最多要进行7级审核^_^,让小七至今都记忆犹新。因为当时工期紧张,小七和伙伴们直接就上了if-else大法。现在想一想其实可以做的设计有很多,比如引入流程引擎,或者使用责任链模式编写代码都可以。
需求背景
现在有三级审核,需要根据时间段的不同设置不同的审核策略。
1、每月1-10号只需要三级审批;
2、每月11-20号,需要二级审批 + 三级审批;
3、每月21号及以后,需要一级审批+二级审批 + 三级审批;
要求不能引入流程引擎等框架,只能使用原生Java实现。
分析设计
根据需求我们可以将审核的全流程看做是一个链路,而具体是哪几级审核可以看做是链路上的节点,或者是子链路,我们要想办法将这些链路连接起来,参考以前学过的建造者模式,我们可以考虑抽象一个类,里面提供一个方法,传入自己并且返回自己
JAVA
public abstract class AuditChain{
private AuditChain next;
public AuditChain addChain(AuditChain next) {
this.next = next;
return this;
}
}
再提供一个方法,移动链路,以便执行每个子链路自己的业务
java
public AuditChain next() {
return next;
}
这样基础的抽象类框架就搭建好了。再往里面填充我们的业务方法,延迟到子类实现就可以了。
UML图
根据分析设计,我们可以先画一个简单的UML图,后面通过UML图编码
模块名称
responsibilitychain
模块地址
模块描述
责任链模式代码示例
代码实现
1、编写接口
提供两个方法
①、获取下一个链路的方法
②、添加下一个链路的方法
java
/**
* 链路处理接口
* 关注公众号【奔跑的码畜】,一起进步不迷路
*
* @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
kotlin
public AuditChain addChain(AuditChain next) {
this.next = next;
return this;
}
java
/**
* 审核链抽象类
* 关注公众号【奔跑的码畜】,一起进步不迷路
*
* @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、编写具体实现类
一级审核
java
/**
* 链路:一级审核
* 大于等于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);
}
}
}
二级审核
java
/**
* 链路:二级审核
* 大于等于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);
}
}
}
三级审核
java
/**
* 链路:三级审核、
* 三级审核不能跳过
* 关注公众号【奔跑的码畜】,一起进步不迷路
*
* @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、编写测试类
java
/**
* 测试责任链模式
* 关注公众号【奔跑的码畜】,一起进步不迷路
*
* @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号后的审批流程====>三级负责人:经办人小王 审核通过
====>二级负责人:李科 审核通过
====>一级负责人:张处 审核通过
====>未找到下级审核人,流程结束
实现要点
模板模式实现要点如下:
-
定义一个抽象处理器类,该类包含一个指向下一个处理器的引用,并定义一个处理方法。
例子中为:抽象处理器类-AuditChain,引用next,处理方法addChain。
-
创建具体的处理器类,每个处理器类都继承自抽象处理器类,并实现处理方法。在处理方法中,首先判断当前处理器是否可以处理请求,如果可以则处理请求,否则将请求传递给下一个处理器。
例子中为:Level1Chain、Level2Chain、Level3Chain的audit方法。
-
客户端代码创建一个处理器链,并将请求从链的一端传递到另一端。
例子中为:
javaAuditChain auditChain = new Level3Chain("10086", "经办人小王") .addChain(new Level2Chain("002", "李科") .addChain(new Level1Chain("001", "张处")));
总结
责任链模式是一种行为型设计模式,它旨在将请求的发送者和接收者分离,使多个处理对象都有可能接收并处理请求。