目录
责任链模式的概念
很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。
发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。
为了避免请求发送者与多个请求处理者耦合在一起,于是将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链。当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。
责任链模式类图
此处已实际工作中的一个支付商户申请流程为例
责任链模式的应用场景
servlet中的filterchain
structs中的拦截器栈
OA工作流之审批流
工作实战
场景描述:我们在进行第三方支付系统的对接中,往往需要申请对应的收单商户,用来做业务交易。接下来的例子是一个系统商为其下属商户申请收单商户的业务场景。
系统商的角色:与支付渠道对接,为下属商户提供商户与用户间的交易能力
子商户的角色:有收款场景的商户(水果店,便利店等)
申请流程:
1、收集商户开通支付渠道所需的资质,如姓名、联系方式、身份证照、银行卡照等
2、系统商将收集的商户信息进行批次处理,去支付渠道进行商户申请
申请成功:修改申请状态为待审核
申请失败:修改申请状态为为通过,并记录申请失败原因
3、将待审核的记录进行批次处理,去支付渠道查询最终申请状态
申请成功:修改申请状态为已通过
申请失败:修改申请状态为未通过,并记录申请失败原因
通过以上流程多少的会发现一些问题:
1、第二步和第三步通过审核状态进行数据区分,并分开进行处理,逻辑处理过于分散
2、待审核的记录为什么不立即进行最终申请状态的查询,而要分步去处理
带着如上的问题,我们结合责任链模式的设计思想与实际业务进行了切合,并产出如下的实现方式
责任链模式的代码实现
1、定义抽象工作流程类,封装业务流转方法供子类使用,其中核心代码是auditFlow() 方法
他根据数据的状态,将请求指派给对应的责任类去处理
public abstract class PayMerchantAuditHandler {
//当前责任类负责的状态
private int auditState;
//如果处理状态非本责任类应该处理的,则设置下个状态处理的责任类
private PayMerchantAuditHandler nextAuditHandler;
private PayMerchantAuditRequest auditRequest;
private boolean finish;
public void setNextAuditHandler(PayMerchantAuditHandler nextAuditHandler) {
this.nextAuditHandler = nextAuditHandler;
}
public int getAuditState() {
return auditState;
}
public void setAuditState(int auditState) {
this.auditState = auditState;
}
public PayMerchantAuditRequest getAuditRequest() {
return auditRequest;
}
public void setAuditRequest(PayMerchantAuditRequest auditRequest) {
this.auditRequest = auditRequest;
}
public boolean isFinish() {
return finish;
}
public void setFinish(boolean finish) {
this.finish = finish;
}
//处理工作流
//待处理状态是否和本责任类状态一致,如果一致,则进行相应的业务处理,否则传递给下个责任类
//如果上个责任类要求进行下个流程处理,则业务方法需返回true
public void auditFlow(PayMerchantAuditRequest auditRequest) {
//流程结束标记,健壮性判空
if (flowFinish() || nextAuditHandler == null)
return;
setAuditRequest(auditRequest);
if (getAuditState() == auditRequest.getState()) {
if (businessHandle()) {
nextAuditHandler.auditFlow(auditRequest);
}
} else {
nextAuditHandler.auditFlow(auditRequest);
}
}
//避免当前责任类初始化时依赖未初始化
protected abstract void initNextHandler();
//可根据业务场景选择性设置是否立即结束当前审批流程
protected abstract boolean flowFinish();
//业务处理类
protected abstract boolean businessHandle();
}
2、创建不同职责的处理类
初始化数据处理类,处理类只关注本类的业务职责,不耦合其他职责
@Component
public class PayMerchantAuditSubmitHandler extends PayMerchantAuditHandler {
@Resource
private PayMerchantAuditPendingHandler nextHandler;
public PayMerchantAuditSubmitHandler() {
setAuditState(0);
}
@PostConstruct
@Override
protected void initNextHandler() {
setNextAuditHandler(nextHandler);
}
@Override
protected boolean flowFinish() {
return false;
}
/**
* 职责:处理state = 0的申请信息
* 业务流程:
* 调用支付渠道入网接口,接口处理成功,修改state = 1;接口处理失败,修改state = 3;
*/
@Override
protected boolean businessHandle() {
LogUtils.getInfoLogger().info("初始化状态处理,state = 0");
getAuditRequest().setState(1);
return Boolean.TRUE;
}
}
待审核状态处理类
@Component
public class PayMerchantAuditPendingHandler extends PayMerchantAuditHandler {
@Resource
private PayMerchantAuditConfirmHandler nextHandler;
public PayMerchantAuditPendingHandler() {
setAuditState(1);
}
@PostConstruct
@Override
protected void initNextHandler() {
setNextAuditHandler(nextHandler);
}
@Override
protected boolean flowFinish() {
return false;
}
/**
* 职责:处理state = 1的申请信息
* 业务流程:
* 调用支付渠道入网查询接口,入网成功,修改state = 2;入网失败,修改state = 3;
*/
@Override
protected boolean businessHandle() {
LogUtils.getInfoLogger().info("待审核状态处理,state = 1");
return Boolean.TRUE;
}
}
总结:以上是将责任链模式与实际业务场景进行了结合
具体职责类只关注本职责类的职责
将不属于自身职责的请求进行向下传递,直到找到相应的责任类进行处理
基于责任链模式进行了扩展,可以将分步的处理进行整合
高内聚,低耦合,是程序员一直要追求的目标。