简介
定义:给多个对象处理请求的机会,减少请求的发送者与接受者之间的耦合。将接受对象链接起来,在链中传递请求,直到有一个对象处理这个请求。
速记:责任传递
案例:财务报销、击鼓传花、Sentinel(CtSph.java)、Zookeeper、Nacos
我考虑对创建订单的流程通过责任链模式的方式进行重构,先来看看我创建订单的流程。
创建订单 -> 消耗优惠券 -> 发货 -> 返利
环境介绍:
jdk 1.8 , spring 5.2.x
代码实现
代码实现入下图所示,通过 AbstractOrderHandler
定义抽象的接口,规范 Handler 的行为,在我的场景下有 4 个 Handler : 1、CreateOrderHandler 创建订单。 2、UseCouponOrderHandler 使用优惠券 3、GoodsDeliverOrderHandler 商品发货 4、RebateOrderHandler 营销返现 通过这样的设计我们就可以巧妙的,将繁杂的流程,进行水平拆分为 Handler ,将之前的 BIG Method ,拆分成了一个可以复用的低耦合的类文件。下面是一个类的示意图:
定义抽象方法
AbstractOrderHandler
定义如下,主要是有两个作用,定义 doHandle
抽象方法,以及为后期按照类型区分 Handler 业务的的 getTypeEnum
方法。
public abstract class AbstractOrderHandler { /** * 区分类型 * * @return */ protected abstract OrderTypeEnum getTypeEnum(); /** * 核心处理 * * @param context 上下文 * @param args 拓展参数 */ public void doHandle(OrderHandleContext context, OrderHandlerChain chain, Object... args) { // 我是否可以处理 if (Objects.isNull(getTypeEnum()) || Objects.equals(context.getTypeEnum(), getTypeEnum())) { // 让我来处理 doHandle(context, args); } // 我处理完了,交给下家 chain.handle(context, args); } /** * 具体业务处理 * * @param context * @param args */ protected abstract void doHandle(OrderHandleContext context, Object... args); }
责任链的实现
具体的 Handler 实现,这里我列举了两个 Handler 的代码,分别是 CreateOrderHandler 创建订单、RebateOrderHandler 营销返利。核心逻辑即使实现 AbstractOrderHandler 接口,并且实现内部的细分逻辑。
// 创建订单 @Slf4j @Service @Order(100) public class CreateOrderHandler extends AbstractOrderHandler { @Override protected OrderTypeEnum getTypeEnum() { return null; } @Override protected void doHandle(OrderHandleContext context, Object... args) { log.info("default create order ... "); // 锁定库存 lockSku(context, args); // 保存订单 saveOrder(context); // 扣除库存 deductSku(context, args) } } // 订单反现金 @Service @Slf4j @Order(200) public class RebateOrderHandler extends AbstractOrderHandler { @Override protected OrderTypeEnum getTypeEnum() { return null; } @Override protected void doHandle(OrderHandleContext context, Object... args) { log.info("default rebate order ... "); } }