当前位置: 首页 > news >正文

责任链设计模式

责任链设计模式(Chain of Responsibility Pattern)是一种行为设计模式,它允许多个对象都有机会处理请求,从而避免请求的发送者与接收者之间的耦合。责任链模式通过将这些对象连成一条链,并沿着这条链传递请求,直到某个对象处理它为止。

1. 基础代码示例

/*** cyt 20240814 根据参数查找运费模板* @param waybillDTO * @return 运费模板实体*/private CarriageEntity findCarriage(WaybillDTO waybillDTO) {// 1. 如果是同城。。。处理逻辑。。。return carriageEntity;// 2. 如果是同省。。。处理逻辑。。。return carriageEntity;// 3. 如果是经济区。。。处理逻辑。。。return carriageEntity;// 4. 跨省。。。处理逻辑。。。return carriageEntity;}

在上述的代码中,判断了很多种情况,如果后续要再增加不同类型的模板或者调整模板之间的优先级,就必须改动代码,所以这样的实现扩展性并不好,也不够灵活。这里可以通过【责任链设计模式】来优化。

之所以采用【责任链】模式,是因为在查找模板时,不同的模板处理逻辑不同,并且这些逻辑组成了一条处理链,有开头有结尾,只要能找到符合条件的模板即结束。

2.责任链模式优化代码

2.1 定义处理链抽象类

1. nextHandler:记录下一个处理器

2. setNextHandler:给nextHander赋值

3. doHandler:抽象方法,由具体的处理器实现,用于处理运费模板的查找逻辑

4、doNextHander:已经实现好的,调用下一个处理器的方法

/*** 运费模板处理链的抽象定义*/
public abstract class AbstractCarriageChainHandler {private AbstractCarriageChainHandler nextHandler;/*** 执行过滤方法,通过输入参数查找运费模板** @param waybillDTO 输入参数* @return 运费模板*/public abstract CarriageEntity doHandler(WaybillDTO waybillDTO);/*** 执行下一个处理器** @param waybillDTO     输入参数* @param carriageEntity 上个handler处理得到的对象* @return*/protected CarriageEntity doNextHandler(WaybillDTO waybillDTO, CarriageEntity carriageEntity) {if (nextHandler == null || carriageEntity != null) {//如果下游Handler为空 或 上个Handler已经找到运费模板就返回return carriageEntity;}return nextHandler.doHandler(waybillDTO);}/*** 设置下游Handler** @param nextHandler 下游Handler*/public void setNextHandler(AbstractCarriageChainHandler nextHandler) {this.nextHandler = nextHandler;}
}

2.2 实现具体的处理器

定义顺序,继承处理链抽象类,实现doHander抽象方法,在doHander最后返回doNextHander。

2.2.1 同城寄

/*** 同城寄*/
@Order(100) //定义顺序
@Component
public class SameCityChainHandler extends AbstractCarriageChainHandler {@Overridepublic CarriageEntity doHandler(WaybillDTO waybillDTO) {。。。处理逻辑。。。return doNextHandler(waybillDTO, carriageEntity);}
}

2.2.2  省内寄

/*** 省内寄*/
@Order(200) //定义顺序
@Component
public class SameProvinceChainHandler extends AbstractCarriageChainHandler {@Overridepublic CarriageEntity doHandler(WaybillDTO waybillDTO) {。。。处理逻辑。。。return doNextHandler(waybillDTO, carriageEntity);}
}

2.2.3 经济区互寄

/*** 经济区互寄*/
@Order(300) //定义顺序
@Component
public class EconomicZoneChainHandler extends AbstractCarriageChainHandler {@Overridepublic CarriageEntity doHandler(WaybillDTO waybillDTO) {    。。。处理逻辑。。。return doNextHandler(waybillDTO, carriageEntity);}
}

2.2.4 跨省寄

/*** 跨省*/
@Order(400) //定义顺序
@Component
public class TransProvinceChainHandler extends AbstractCarriageChainHandler { @Overridepublic CarriageEntity doHandler(WaybillDTO waybillDTO) {。。。处理逻辑。。。return doNextHandler(waybillDTO, carriageEntity);}
}

2.3 组装处理链

 组装处理链,按照@Order注解中的值,由小到大排序。

/*** 查找运费模板处理链 @Order注解指定handler顺序*/
@Component
public class CarriageChainHandler {/*** 利用Spring注入特性,按照 @Order 从小到达排序注入到集合中*/@Resourceprivate List<AbstractCarriageChainHandler> chainHandlers;private AbstractCarriageChainHandler firstHandler;/*** 组装处理链*/@PostConstruct // Spring自动调用该方法private void constructChain() {if (CollUtil.isEmpty(chainHandlers)) {throw new SLException("not found carriage chain handler!");}//处理链中第一个节点firstHandler = chainHandlers.get(0);for (int i = 0; i < chainHandlers.size(); i++) {if (i == chainHandlers.size() - 1) {//最后一个处理链节点chainHandlers.get(i).setNextHandler(null);} else {//设置下游节点chainHandlers.get(i).setNextHandler(chainHandlers.get(i + 1));}}}public CarriageEntity findCarriage(WaybillDTO waybillDTO) {//从第一个节点开始处理return firstHandler.doHandler(waybillDTO);}}

@PostConstruct:这个注解标注的方法会在 Spring 完成依赖注入后自动调用,用来初始化责任链。

3. 总结

调用carriageChainHandler.findCarriage(waybillDTO)方法和直接调用基础代码示例中的findCarriage(waybillDTO)方法,效果相同,完成了责任链模式的代码优化。

通过这种设计,如果将来需要新增处理逻辑或调整处理顺序,只需新建处理器类或调整 @Order 注解的值,而无需修改现有的代码结构,极大地提高了代码的可维护性和扩展性。


http://www.mrgr.cn/news/1187.html

相关文章:

  • 【python数据分析08】——Pandas统计分析(读/写不同数据源的数据)
  • 【体检】程序人生之健康检查,全身体检与预防疫苗,五大传染病普筛,基因检测等
  • 手机使用技巧:如何恢复Android手机不见的短信
  • C++--map和set
  • 桶射巡飞无人机技术详解
  • 解析已有架构+文心快码(Baidu Comate)软件架构
  • Java二十三种设计模式-中介者模式(22/23)
  • 【Rust光年纪】深度剖析Rust数据科学库:统计分析、概率可视化和回归分析应有尽有
  • dockerfile
  • JavaScript - Ajax
  • 微信小程序骨架屏
  • 前端post传入拿到数据,后端报null,并且能够添加或者编辑成功
  • CreateFile()逻辑梳理(二)
  • stl---vector
  • 工业三防平板在数字化工厂建设中的重要趋势
  • 【Linux入门】Linux常见指令
  • SpinalHDL之spinal.core 组件(下篇)
  • C语言随笔:内存相关的一些...
  • 使用git时出现的问题总结
  • 应急响应-DDOS-典型案例