简介
责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。
在这种模式中,有多个对象,每个对象持有对下一个对象的引用,这样就会形成一条链,请求在这条链上传递,直到某一对象决定处理该请求。但是发出者并不清楚到底最终哪个对象会处理该请求,所以,责任链模式可以实现,在客户端的无感知的情况下,对系统进行动态的调整。
场景
- 有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定
- 在不明确指定接收者的情况下,向多个对象中的一个提交一个请求
- 动态指定一组对象处理请求
运用
背景
审核系统在接受业方提交的审核请求以后,先进行审核前置校验;校验通过后,将进行审核单本地初始化,进行存储处理,否则结束流程;最后请求将进入审核后置处理,如,一些业务流程通知等操作。
责任链接口
public interface XiuChain<T> {
/**
* 操作
* @param t 上下文
*/
void handle(T t);
}
责任链抽象
@Data
public abstract class AbstractXiuChain<T> {
private XiuChain<T> chain;
}
责任链实现
预处理
@Slf4j
@Component
public class BeforeAuditChain extends AbstractXiuChain<AuditContext> implements XiuChain<AuditContext> {
@Override
public void handle(AuditContext auditContext) {
log.info("审核流水:{},执行预处理开始.", auditContext.getTradeFlowNo());
// 逻辑处理忽略
if (getChain() != null) {
getChain().handle(auditContext);
}
}
}
初始化
@Slf4j
@Component
public class InitAuditChain extends AbstractXiuChain<AuditContext> implements XiuChain<AuditContext> {
@Override
public void handle(AuditContext auditContext) {
log.info("审核流水:{},执行初始化开始.", auditContext.getTradeFlowNo());
// 逻辑处理忽略
if (getChain() != null) {
getChain().handle(auditContext);
}
}
}
后置处理
@Slf4j
@Component
public class PostAuditChain extends AbstractXiuChain<AuditContext> implements XiuChain<AuditContext> {
@Override
public void handle(AuditContext auditContext) {
log.info("审核流水:{},执行后置处理开始.", auditContext.getTradeFlowNo());
// 逻辑处理忽略
if (getChain() != null) {
getChain().handle(auditContext);
}
}
}
单元测试
public class AuditChainTest extends BaseTest {
@Resource
private BeforeAuditChain beforeAuditChain;
@Resource
private InitAuditChain initAuditChain;
@Resource
private PostAuditChain postAuditChain;
@Test
public void submitOrder() {
// 模拟业务提交审核参数
AuditContext auditContext = AuditContext.builder()
.tradeFlowNo("OID202205071551431-110000-01-123")
.auditContent("审核内容")
.build();
// 审核前置-> 审核
beforeAuditChain.setChain(initAuditChain);
// 审核 -> 审核后置
initAuditChain.setChain(postAuditChain);
// 执行指令
beforeAuditChain.handle(auditContext);
}
}
总结
1、低耦合、高内聚
将请求的发送者和接收者解耦,对发送者黑盒无感
2、灵活性
改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任
3、在一个时刻,命令只允许由一个对象传给另一个对象,而不允许传给多个对象