当前位置: 首页 > 科技观察

责任链模式

时间:2023-03-18 16:03:58 科技观察

介绍设计模式的定义:给多个对象处理请求的机会,降低请求发送者和接收者之间的耦合度。链接接受对象,在链中传递请求,直到对象处理请求。简写:责任转移案例:财务报销、打鼓、Sentinel(CtSph.java)、Zookeeper、Nacos我考虑重构通过责任链模型创建订单的流程。首先,让我们看一下我创建订单的过程。创建订单->消费优惠券->发货->返利环境介绍:jdk1.8,spring5.2.x代码实现代码实现如下图所示,通过AbstractOrderHandler定义抽象接口,Handler的行为为标准化。在我的场景中,有4个处理程序:1.CreateOrderHandler创建一个订单。2.UseCouponOrderHandler使用优惠券3.GoodsDeliverOrderHandler商品配送4.RebateOrderHandlerMarketingCashback通过这样的设计,我们可以巧妙地将复杂的流程横向拆分成Handlers,将之前的BIGMethod拆分成一个可重用的低耦合类文件。下面是一个类的示意图:抽象方法AbstractOrderHandler的定义如下,主要有两个作用,doHandle抽象方法的定义,以及后面根据类型区分Handler业务的getTypeEnum方法。publicabstractclassAbstractOrderHandler{/***区分类型**@return*/protectedabstractOrderTypeEnumgetTypeEnum();/***核心处理**@paramcontext上下文*@paramargs扩展参数*/publicvoiddoHandle(OrderHandleContextcontext,OrderHandlerChainchain,Object...args){//我可以处理吗if(Objects.isNull(getTypeEnum())||Objects.equals(context.getTypeEnum(),getTypeEnum())){//让我处理doHandle(context,args);}//我处理后,交给下一个chain.handle(context,args);}/***具体业务处理**@paramcontext*@paramargs*/protectedabstractvoiddoHandle(OrderHandleContextcontext,Object...args);}负责执行chain是具体的Handler实现,这里我列举两个Handler代码,分别是创建订单的CreateOrderHandler和返利营销的RebateOrderHandler。核心逻辑甚至实现了AbstractOrderHandler接口,实现了内部的细分逻辑。//创建订单@Slf4j@Service@Order(100)publicclassCreateOrderHandlerextendsAbstractOrderHandler{@OverrideprotectedOrderTypeEnumgetTypeEnum(){returnull;}@OverrideprotectedvoiddoHandle(OrderHandleContextcontext,Object...args){log.info("defaultcreateorder...");//lockInventorylockSku(context,args);//保存订单saveOrder(context);//扣除库存deductSku(context,args)}}//订单反现@Service@Slf4j@Order(200)publicclassRebateOrderHandlerextendsAbstractOrderHandler{@OverrideprotectedOrderTypeEnumgetTypeEnum(){returnnull;}@OverrideprotectedvoiddoHandle(OrderHandleContextcontext,Object...args){log.info("defaultrebateorder...");}}定义了调用入口OrderHandlerChain是外部调用的入口,其实它的主要作用是获取AbstractOrderHandler并排序(即Handler的拼接/排列)然后执行。这里我充分利用了Spring的Bean排序功能。通过在Handler上定义@Order注解并传入order值,当我们用@Autowired获取List时,Spring会自动为我注入排序后的handlerList。@Slf4j@ComponentpublicclassOrderHandlerChain{@AutowiredprivateList链;@AutowiredprivateApplicationContextapplicationContext;publicvoidhandle(OrderHandleContextcontext,Object...objects){if(context.getPos()