Java设计模式之责任链模式(Chain of Responsibility Pattern)

目录

责任链模式的概念

责任链模式类图

责任链模式的应用场景

工作实战

责任链模式的代码实现


责任链模式的概念

很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。

发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。

为了避免请求发送者与多个请求处理者耦合在一起,于是将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链。当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。

责任链模式类图

此处已实际工作中的一个支付商户申请流程为例

责任链模式的应用场景

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;
    }
}

总结:以上是将责任链模式与实际业务场景进行了结合

具体职责类只关注本职责类的职责

将不属于自身职责的请求进行向下传递,直到找到相应的责任类进行处理

基于责任链模式进行了扩展,可以将分步的处理进行整合

高内聚,低耦合,是程序员一直要追求的目标。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
责任链模式Chain of Responsibility Pattern)是一种行为设计模式,它通过将请求的发送者和接收者解耦,使多个对象都有机会处理该请求。在责任链模式中,每个对象都持有对下一个对象的引用,形成一条,依次处理请求,直到有一个对象能够处理它为止。 在 MyBatis 框架中,Interceptor(拦截器)和 InitializingBean(初始化 Bean)是两个常用的接口,用于实现责任链模式和 Bean 初始化。 以下是一个简单的示例代码: ```java // Interceptor 接口 public interface Interceptor { Object intercept(Invocation invocation) throws Throwable; } // Invocation 对象 public class Invocation { private Object target; // 目标对象 private Method method; // 目标方法 private Object[] args; // 参数 // 省略构造方法和 getter/setter } // MyInterceptor 实现 Interceptor 接口 public class MyInterceptor implements Interceptor { @Override public Object intercept(Invocation invocation) throws Throwable { // 在拦截器中实现自定义逻辑 System.out.println("Before method execution"); Object result = invocation.getMethod().invoke(invocation.getTarget(), invocation.getArgs()); System.out.println("After method execution"); return result; } } // InitializingBean 接口 public interface InitializingBean { void afterPropertiesSet() throws Exception; } // MyBean 实现 InitializingBean 接口 public class MyBean implements InitializingBean { @Override public void afterPropertiesSet() throws Exception { // 初始化 Bean 后执行的逻辑 System.out.println("Bean initialized"); } } ``` 在上面的示例中,`MyInterceptor` 实现了 `Interceptor` 接口,其中的 `intercept` 方法可以在目标方法执行前后添加自定义逻辑。 `Invocation` 对象用于封装目标方法的相关信息,包括目标对象、方法和参数。 `MyBean` 实现了 `InitializingBean` 接口,在 `afterPropertiesSet` 方法中可以添加初始化 Bean 后执行的逻辑。 在实际使用中,可以通过配置文件或注解将拦截器和初始化 Bean 注入到 MyBatis 或 Spring 容器中,从而实现责任链模式和 Bean 初始化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值