**业务背景:**在实际购票业务场景中,用户发起一次购票请求后,购票接口在真正完成创建订单和扣减余票行为前,需要验证当前请求中的参数是否正常请求,或者说是否满足购票;
1.购票请求用户传递的参数是否为空,比如:车次ID、乘车人、出发站点、到达站点等;
2.购票请求用户传递的参数是否正确,比如:车次ID是否存在、出发站点和到达站点是否存在等。
3.需要购票的车次是否满足乘车人的数量,也就是车座余位是否充足;
4.乘客是否已经购买车次,或者乘客是否已经购买与当天冲突的车次;
5.实际场景中需要验证的还有很多;
解决前置校验需求需要实现一堆逻辑,尝尝需要写上几百上千行的代码。并且,其中的代码不具备开闭原则(一旦需求的变更就会导致代码的修改,这不仅会增加代码风险,还会增加我们的开发、测试和维护成本),以及代码的扩展性,整体来说复杂且臃肿;
因此我们运用责任链的设计模式,对购票验证逻辑进行抽象;
责任链模式的优点在于它可以动态地添加。删除和调整处理这对象,从而灵活的构建处理链。同时,它也避免了请求发送者和接收者之间的紧耦合,增强了系统的灵活性和可扩展性;
具体实现:首先是定义购票责任链过滤接口,其次是对列车购买过滤器的实现,将每个需要验证的业务进行实现类编写,其中重写hanlder方法为具体的业务代码,并定义Order,代表在责任链中验证的顺序。其中购票流程过滤器之验证参数是否有效业务中,存在大量的缓存交互,为了优化性能需要使用Lua.(是什么?为了解决什么问题?),责任链中的业务检测流程有很多,最后对购票流程使用过滤器。
private final AbstractChainContext<PurchaseTicketReqDTO> purchaseTicketAbstractChainContext;
@Override
@Transactional(rollbackFor = Throwable.class)
public TicketPurchaseRespDTO purchaseTickets(PurchaseTicketReqDTO requestParam) {
// 责任链模式,验证 0:参数必填 1:参数正确性 2:列车车次余量是否充足 3:乘客是否已买当前车次等
purchaseTicketAbstractChainContext.handler(TicketChainMarkEnum.TRAIN_PURCHASE_TICKET_FILTER.name(), requestParam);
// ......
}
购票责任链实现原理:1. 运行时获取责任链具体实现类 2. 初始化责任链容器;