1、项目中责任链模式实战
我们使用责任链模式实现对订单中参数的校验,首先校验订单id是否为空,然后校验下单人是否为空,最后检验收获地址是否为空。业务的流程图如下所示:
针对上述的业务,我们使用责任链的模式来实现这个功能:
(1)定义一个责任链的接口
java">public interface OrderCheckHandler {/*** 当前的订单检测实现逻辑* @param orderCheckParam*/void check(OrderCheckParam orderCheckParam);/*** 设置下一个检测的实现逻辑* @param nextOrderCheckHandler* @return*/OrderCheckHandler setNext(OrderCheckHandler nextOrderCheckHandler);
}
(2)责任链中的公共逻辑的抽取
java">public abstract class BaseCheckOrderHandler implements OrderCheckHandler {private OrderCheckHandler nextOrderCheckHandler;@Overridepublic void check(OrderCheckParam orderCheckParam) {this.currentCheck(orderCheckParam);if(Objects.nonNull(nextOrderCheckHandler)){nextOrderCheckHandler.check(orderCheckParam);}}/*** 具体的实现逻辑**/protected abstract void currentCheck(OrderCheckParam orderCheckParam);@Overridepublic OrderCheckHandler setNext(OrderCheckHandler nextOrderCheckHandler) {this.nextOrderCheckHandler = nextOrderCheckHandler;return this.nextOrderCheckHandler;}
}
(3)具体的检验逻辑(继承公共逻辑)
java">-- 订单id校验
public class OrderIdCheckHandler extends BaseCheckOrderHandler {@Overrideprotected void currentCheck(OrderCheckParam orderCheckParam) {if(orderCheckParam.getOrderId() == null){throw new RuntimeException("订单id为空");}}
}
-- 用户校验
public class BuyerCheckHandler extends BaseCheckOrderHandler {@Overrideprotected void currentCheck(OrderCheckParam orderCheckParam) {if(orderCheckParam.getBuyer() == null){throw new RuntimeException("用户不可以为空");}}
}
-- 地址校验
public class AddressCheckHandler extends BaseCheckOrderHandler {@Overrideprotected void currentCheck(OrderCheckParam orderCheckParam) {if(orderCheckParam.getAddress() == null){throw new RuntimeException("用户地址不可以为空");}}
}
(4)使用spring将业务逻辑串联起来
java">@Configuration
public class OrderCheckConfig {@Beanpublic BuyerCheckHandler buyerCheckHandler(){return new BuyerCheckHandler();}@Beanpublic OrderIdCheckHandler checkOrderIdHandler(){return new OrderIdCheckHandler();}@Beanpublic AddressCheckHandler addressCheckHandler(){return new AddressCheckHandler();}//设置责任链得执行链路顺序@Beanpublic OrderCheckHandler orderCheckHandler(){OrderIdCheckHandler orderIdCheckHandler = this.checkOrderIdHandler();orderIdCheckHandler.setNext(this.buyerCheckHandler()).setNext(this.addressCheckHandler());return orderIdCheckHandler;}
}
(5)service调用责任链的
java">@Service
public class OrderService {@Resourceprivate OrderCheckHandler orderCheckHandler;public String checkOrderParam(OrderCheckParam param){orderCheckHandler.check(param);return "success";}
}
(6)controller逻辑
java">@RestController
@RequestMapping("/test")
public class ZeRenLianTestController {@Resourceprivate OrderService orderService;@GetMapping("/checkOrder")public String checkOrder(){OrderCheckParam orderCheckParam = new OrderCheckParam();orderCheckParam.setAddress("123");orderCheckParam.setOrderId("1235689");return orderService.checkOrderParam(orderCheckParam);}
}
如果现在需要增加一种校验(如增加订单物流的校验),此时我们只需要增加一个业务的实现类,然后在spring的配置将这个业务实现类加入到责任链逻辑上就可以了。
总结:
(1)需要保证责任链的结构清晰、避免创建过长的链,进而提升执行的性能。
(2)每个业务应该具有单一职责,每个对象专注于处理自己的逻辑。
(3)责任链模式使用的典型场景是多个对象处理同一个请求,如OA审批、参数的校验、日志记录器链等等。