专业编程基础技术教程

网站首页 > 基础教程 正文

设计模式之责任链模式

ccvgpt 2024-08-20 12:56:45 基础教程 9 ℃

简介

责任链模式(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、在一个时刻,命令只允许由一个对象传给另一个对象,而不允许传给多个对象

Tags:

最近发表
标签列表