设计模式(五)责任链模式——在Spring中使用责任链模式

编程入门 行业动态 更新时间:2024-10-11 01:13:44

设计<a href=https://www.elefans.com/category/jswz/34/1771241.html style=模式(五)责任链模式——在Spring中使用责任链模式"/>

设计模式(五)责任链模式——在Spring中使用责任链模式

前言

在 设计模式(四)责任链模式 —— 责任链模式结构 中分析了责任链模式的结构,在日常开发中经常结合spring容器来使用,借助容器的一些特性,同时可以解决一些责任链模式的不足。

场景案例

如以电商系统下单流程为例,简化一下这个流程,只包含库存、价格、优惠券三个业务步骤。

类图结构

在spring中优雅的使用责任链模式

定义业务用到的基础类

定义OrderDTO和ResultDTO

import java.io.Serializable;/*** @author lishuzhen* @createTime 2022年06月19日 22:40:00*/
public class ResultDTO implements Serializable {private String msg;public static ResultDTO ok(){return new ResultDTO();}public ResultDTO() {msg = "ok";}public String getMsg() {return msg;}
}/*** @author lishuzhen* @createTime 2022年06月19日 22:15:00*/
public class OrderDTO {private String orderNo;public String getOrderNo() {return orderNo;}public void setOrderNo(String orderNo) {this.orderNo = orderNo;}
}

定义抽象的处理器接口

  • 定义doFilter方法,由子类实现处理器的内部逻辑,注意在doFilter方法的最后一步要记得调用doNextFilter()
  • 定义doNextFilter方法,由抽象类完成调用下一个处理器的代码。
/*** 处理器抽象类** @author lishuzhen* @createTime 2022年06月19日 22:52:00*/
public abstract class AbstractOrderChainHandler {private AbstractOrderChainHandler nextHandler;/*** 执行过滤方法** @param orderDTO* @return*/abstract protected ResultDTO doFilter(OrderDTO orderDTO);/*** 执行下一个处理器** @param orderDTO* @param resultDTO* @return*/protected ResultDTO doNextHandler(OrderDTO orderDTO, ResultDTO resultDTO) {if (nextHandler == null) {return resultDTO;}return nextHandler.doFilter(orderDTO);}public void setNextHandler(AbstractOrderChainHandler nextHandler) {this.nextHandler = nextHandler;}
}

定义处理器的子类实现

  • 必须实现抽象的处理器接口,供容器启动时获取所有的处理器实现类
  • 通过@Order注解,标识当前处理器在整个责任链中的位置。建议区间设置的大一些,后续增加处理器时比较方便。
/*** 订单提交-库存计算处理器** @author lishuzhen* @createTime 2022年06月19日 22:57:00*/
@Service
@Order(100)
public class StockOrderChainHandler extends AbstractOrderChainHandler {/*** 执行过滤方法** @param orderDTO* @return*/@Overrideprotected ResultDTO doFilter(OrderDTO orderDTO) {System.out.println("库存计算处理");return doNextHandler(orderDTO, ResultDTO.ok());}
}
/*** 订单提交-价格计算处理器** @author lishuzhen* @createTime 2022年06月19日 22:59:00*/
@Service
@Order(300)
public class PriceOrderChainHandler extends AbstractOrderChainHandler {/*** 执行过滤方法** @param orderDTO* @return*/@Overrideprotected ResultDTO doFilter(OrderDTO orderDTO) {System.out.println("价格计算处理");return doNextHandler(orderDTO, ResultDTO.ok());}
}
/*** 订单提交-优惠券计算处理器** @author lishuzhen* @createTime 2022年06月19日 22:59:00*/
@Service
@Order(200)
public class CouponOrderChainHandler extends AbstractOrderChainHandler {/*** 执行过滤方法** @param orderDTO* @return*/@Overrideprotected ResultDTO doFilter(OrderDTO orderDTO) {System.out.println("优惠券处理");return doNextHandler(orderDTO, ResultDTO.ok());}
}

封装组合责任链

  • 通过@Autowired修饰责任链(处理器的集合),spring容器会按照@order的顺序组装一个有序的list集合。
  • 通过@PostConstruct修饰constructChain()方法,使容器回调此方法,完成为每一个处理设置它的下一个处理器
  • 定义firstHandler,表示这是当前责任链路顶端的第一个处理器。
/*** 订单处理责任链** @author lishuzhen* @createTime 2022年06月19日 23:05:00*/
@Service
public class OrderChainHandler {@Autowiredprivate List<AbstractOrderChainHandler> chain;private AbstractOrderChainHandler firstHandler;@PostConstructprivate void constructChain() {if (chain == null || chain.size() == 0) {throw new RuntimeException("not found order chain handler");}firstHandler = chain.get(0);for (int i = 0; i < chain.size(); i++) {if (i == chain.size() - 1) {chain.get(i).setNextHandler(null);} else {chain.get(i).setNextHandler(chain.get(i + 1));}}}public ResultDTO executionChain(OrderDTO orderDTO) {return firstHandler.doFilter(orderDTO);}
}

写一个测试接口

@Controller
@RequestMapping("/lsz")
public class OrderTestController {@Autowiredprivate OrderChainHandler orderChainHandler;@ResponseBody@RequestMapping("testOrder")public Object testOrder(String orderNo){return orderChainHandler.executionChain(new OrderDTO()).getMsg();}
}

查看日志

可以看到控制台日志按照责任链处理器的顺序打印了日志

总结

优点

  • 降低了各个处理器之间的耦合,各处理器只关注处理自身的内部逻辑,然后抛给下一个处理器即可。
  • 不需要关注具体的上下游调用关系,在组装责任链时通过spring的特性动态注入下一个处理器的调用关系。
  • 通过@Order注解,可灵活调整各处理器之间的调用顺序

缺点

  • 会增加程序的复杂度,需评估酌情使用,不可为了设计模式而用设计模式。

更多推荐

设计模式(五)责任链模式——在Spring中使用责任链模式

本文发布于:2024-02-13 17:48:33,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1759885.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:模式   责任   Spring

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!