责任链模式进行订单校验

文章讲述了在创建订单之前,如何利用责任链模式对订单数据进行多步骤校验,以避免校验逻辑之间的耦合。通过在`@PostConstruct`注解的方法中初始化校验处理器链,并将其交给Spring容器管理,确保了代码的解耦和可维护性。校验过程包括订单参数、商品信息、业务规则等多个环节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

责任链模式

  • 使用场景,在创建订单的前置,需要对订单的数据进行校验,校验有先后且校验的代码较多。为了解耦避免多个校验直接相互环关联影响。同时使用注解@PostConstruct把对应的校验处理器在bean创建阶段就直接交给spring容器进行管理。

  • package com.evatmaster.biz.center.order.service.impl;
    
    import cn.hutool.core.collection.CollectionUtil;
    import com.evatmaster.biz.center.order.service.IOrderCheckBizService;
    import com.evatmaster.biz.center.order.handler.OrderCheckHandler;
    import com.evatmaster.biz.center.order.handler.impl.*;
    import com.evatmaster.biz.center.utils.WhiteListUtil;
    import com.evatmaster.core.enums.order.OrderSourceEnum;
    import com.evatmaster.core.enums.order.OrderTypeEnum;
    import com.evatmaster.core.enums.payment.PayBizTypeEnum;
    import com.evatmaster.core.enums.payment.PayReceivingTypeEnum;
    import com.evatmaster.core.enums.product.ProductTypeEnum;
    import com.evatmaster.core.exception.ValidateException;
    import com.evatmaster.core.utils.CommonUtils;
    import com.evatmaster.core.utils.StringUtils;
    import com.evatmaster.order.api.dto.BuyCartRequestDTO;
    import com.evatmaster.biz.center.order.dto.CreateOrderBizDTO;
    import com.evatmaster.order.api.dto.CreateBuyCartBaseDTO;
    import com.evatmaster.order.api.dto.OrderRequestDTO;
    import com.evatmaster.order.api.enums.OrderPaymentMethodEnum;
    import lombok.RequiredArgsConstructor;
    import org.springframework.beans.BeanUtils;
    import org.springframework.stereotype.Service;
    
    import javax.annotation.PostConstruct;
    import java.util.ArrayList;
    import java.util.List;
    
    
    /**
     * 订单校验接口
     * @author li
     */
    @Service
    @RequiredArgsConstructor
    public class OrderCheckBizServiceImpl implements IOrderCheckBizService {
    
        private final OrderCheckParamHandler  checkParamHandler;
        private final OrderCheckProductHandler checkProductHandler;
        private final OrderCheckSetMealHandler checkSetMealHandler;
        private final OrderCheckActivityHandler checkActivityHandler;
        private final OrderCheckVoucherHandler checkVoucherHandler;
        private final OrderCheckPackVoucherHandler checkPackVoucherHandler;
        private final OrderCheckScoreHandler orderCheckScoreHandler;
        private final OrderCheckBizHandler orderCheckBizHandler;
        private final OrderCheckActivityGroupHandler orderCheckActivityGroupHandler;
        private final OrderCheckAfterPayHandler orderCheckAfterPayHandler;
        private final OrderCheckNewUserZoneHandler orderCheckNewUserZoneHandler;
        private final WhiteListUtil whiteListUtil;
        private final OrderCheckVipUpgradeHandler orderCheckVipUpgradeHandler;
        private final OrderCheckVipHandler orderCheckVipHandler;
        /**
         * 订单检查链路
         */
        private final List<OrderCheckHandler> chain = new ArrayList<>(8);
    
    
        @PostConstruct
        public void initChain(){
            //校验订单参数
            chain.add(checkParamHandler);
            //校验商品信息
            chain.add(checkProductHandler);
            //校验业务
            chain.add(orderCheckBizHandler);
            // 套餐校验
            chain.add(checkSetMealHandler);
            // 校验先用后付
            chain.add(orderCheckAfterPayHandler);
            // 校验新人专区
            chain.add(orderCheckNewUserZoneHandler);
            //校验活动
    //        chain.add(checkActivityHandler);
            // 校验拼团
            chain.add(orderCheckActivityGroupHandler);
            //校验优惠券
            chain.add(checkVoucherHandler);
            //校验服务兑换券
            chain.add(checkPackVoucherHandler);
            //校验积分
            chain.add(orderCheckScoreHandler);
            // 校验VIP升级商品
            chain.add(orderCheckVipUpgradeHandler);
            // 校验会员商品
            chain.add(orderCheckVipHandler);
        }
        @Override
        public CreateOrderBizDTO checkOrder(OrderRequestDTO order) {
            if(CollectionUtil.isEmpty(order.getDetailDTOList())){
                throw new ValidateException("请选择购买的商品");
            }
            CreateOrderBizDTO dto = CreateOrderBizDTO.of(order);
            String payWay = dto.getPayWay() + "";
            // 大客户批量创单,未指定支付方式,则默认微信支付
            if(StringUtils.isBlank(payWay) && OrderSourceEnum.BATCH_CREATE.is(String.valueOf(order.getOrderSource()))) {
                payWay = PayReceivingTypeEnum.WECHAT.getCode();
            }
            // 支付宝扫码支付、微信扫码支付、小程序微信支付
            if(PayReceivingTypeEnum.ALIPAY.is(payWay) || PayReceivingTypeEnum.WECHAT.is(payWay) || PayReceivingTypeEnum.APPLET.is(payWay)) {
                Integer payChannel = whiteListUtil.getPayChannel(order.getMercName(), dto.getSystemType(), PayBizTypeEnum.BUY.name());
                Integer payMethod = OrderPaymentMethodEnum.parsePayChannel(payChannel, payWay);
                dto.setPaymentMethod(payMethod);
            }
            // 对公转账
            if(PayReceivingTypeEnum.OFFLINE.is(payWay)) {
                dto.setPaymentMethod(OrderPaymentMethodEnum.OFFLINE.getValue());
            }
            // 余额支付
            if(PayReceivingTypeEnum.BALANCE_RECHARGE_PAY.is(payWay)) {
                dto.setPaymentMethod(OrderPaymentMethodEnum.BALANCE_RECHARGE_PAY.getValue());
            }
            //券包兑换
            if (null != order.getPackageId()){
                dto.setPaymentMethod(OrderPaymentMethodEnum.VOUCHER_SERVICE.getValue());
            }
            //余额充值要标记为官费商品
            if (OrderTypeEnum.BALANCE_RECHARGE_ORDER.getCode().equals(order.getOrderType())){
                dto.setProductType(ProductTypeEnum.OFFICIAL.getValue());
            }
            //将请求参数对象转换成业务对象
            return checkOrder(dto);
        }
    
        @Override
        public CreateBuyCartBaseDTO checkBuyCart(BuyCartRequestDTO dto) {
            CreateOrderBizDTO createOrderBizDTO = checkOrder(dto);
            CreateBuyCartBaseDTO result = new CreateBuyCartBaseDTO();
            BeanUtils.copyProperties(createOrderBizDTO,result);
            result.setCartType(dto.getCartType());
            return result;
        }
    
        /**
         * 执行检查
         * @param dto
         * @return
         */
        private CreateOrderBizDTO checkOrder(CreateOrderBizDTO dto){
            for (OrderCheckHandler orderCheckHandler : chain) {
                orderCheckHandler.check(dto);
            }
            return dto;
        }
    }
    
    --------------------------------------------执行器------------------------------------------
    package com.evatmaster.biz.center.order.handler.impl;
    
    import com.evatmaster.biz.center.order.dto.CreateOrderDetailBizDTO;
    import com.evatmaster.biz.center.order.handler.OrderCheckHandler;
    import com.evatmaster.biz.center.order.dto.CreateOrderBizDTO;
    import com.evatmaster.core.enums.order.OrderTypeEnum;
    import com.evatmaster.core.exception.ValidateException;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.stereotype.Service;
    
    /**
     * 订单商品校验,并且填充商品数据
     * @author li
     */
    @Service("orderParamCheckHandler")
    @Slf4j
    public class OrderCheckParamHandler implements OrderCheckHandler {
    
        @Override
        public void check(CreateOrderBizDTO vo) {
            for (CreateOrderDetailBizDTO dto : vo.getDetailDTOList()) {
                if (dto.getSkuId() == null) {
                    throw new ValidateException("请选择够买的服务");
                }
    
                //最大服务数量校验  增值服务不校验
                if (dto.getPurchaseQuantity() > 99 && !dto.isAttachOrder()) {
                    throw new ValidateException("单个服务数量不能超过99");
                }
                //官费订单
                if(vo.getOrderType() != null && vo.getOrderType().intValue() == OrderTypeEnum.OFFICIAL_ORDER.getCodeInt() && dto.getPurchaseQuantity() > 1){
                    throw new ValidateException("官费订单数量不能大于1");
                }
    
            }
        }
    
    }
    
    

使用

    @Override
    public R<CreateOrderResultVo> createOrder(OrderRequestDTO order) {
        String orderNumber = RedisSequence.getOrderSeq(order.getOrderType());
        //合规帮手下单来源
        if("captain".equals(this.getLoginFrom())){
            order.setOrderSource(OrderSourceEnum.COMPLIANCE_HRLPER.getIntValue());
        }


        //2.校验订单数据、填充订单中的业务商品、活动等数据数据
        CreateOrderBizDTO bizDTO = orderCheckBizService.checkOrder(order);
	}
---------------------------------------------------
package com.evatmaster.biz.center.order.service;

import com.evatmaster.biz.center.order.dto.CreateOrderBizDTO;
import com.evatmaster.order.api.dto.BuyCartRequestDTO;
import com.evatmaster.order.api.dto.CreateBuyCartBaseDTO;
import com.evatmaster.order.api.dto.OrderRequestDTO;

/**
 * 订单校验接口
 * @author li
 */
public interface IOrderCheckBizService  {
    /**
     * 创建订单校验
     * @param order
     * @return
     */
    CreateOrderBizDTO checkOrder(OrderRequestDTO order);

    /**
     * 创建订单校验
     * @param dto
     * @return
     */
    CreateBuyCartBaseDTO checkBuyCart(BuyCartRequestDTO dto);


}

1

<think>好的,我需要帮助用户了解若依框架中责任链模式的实现与用法。首先,我应该回忆责任链模式的基本概念,确保自己理解正确。根据用户提供的引用,责任链模式主要是解耦请求和处理,让请求在链中传递,每个处理者决定处理或转发请求。这能提高系统的灵活性和可扩展性,比如在Spring中的应用。 接下来,用户问的是若依框架中的具体实现。若依是一个基于Spring Boot的权限管理系统,所以它的责任链模式可能和Spring的机制类似。我需要结合用户提供的引用,特别是引用3提到的Spring Boot中使用责任链模式进行多级校验的例子,来推测若依可能的实现方式。 首先,责任链模式的结构通常包含一个处理器接口,多个具体处理器,以及一个链条来管理这些处理器。在若依框架中,可能使用Spring的依赖注入来组装责任链。例如,定义一个Handler接口,多个实现类,然后通过@Autowired或@Resource注入一个处理器列表,按照特定顺序执行。 然后,用户可能想知道具体的代码示例。根据引用3中的例子,若依可能也有类似的校验流程,比如订单处理、权限校验等。我需要构建一个简单的示例,展示如何定义处理器接口,实现具体处理器,并通过Spring管理链条。 另外,用户提供的引用提到责任链的优点,比如解耦逻辑、灵活扩展,这些应该在若依的实现中体现出来。例如,新增处理器只需添加新的实现类,而无需修改现有代码,这样符合开闭原则。 可能还需要考虑若依框架中责任链的使用场景,比如日志记录、权限校验、工作流审批等。需要结合具体的业务模块来举例说明,比如在审批流程中,每个处理节点可能对应一个处理器,依次传递请求直到处理完毕。 需要注意的是,若依框架可能有自己的特定实现方式,可能与标准Spring Boot有所不同。因此,在回答时应尽量基于通用的Spring Boot责任链实现方法,并提到若依可能在此基础上进行扩展或调整。 最后,要确保回答结构清晰,分步骤说明实现方式,并给出代码示例,这样用户能逐步理解。同时,生成的相关问题需要围绕责任链模式的扩展、性能优化、应用场景等,帮助用户深入思考。</think>### 若依框架中责任链模式的实现与使用分析 #### 1. 责任链模式的核心实现 若依框架(基于Spring Boot)通过以下方式实现责任链模式: - **处理器接口定义** 定义统一处理接口,强制所有具体处理器实现`handle()`方法: ```java public interface Handler<T> { void handle(T request); void setNext(Handler<T> next); } ``` - **具体处理器实现** 每个处理器实现业务逻辑,并决定是否传递请求: ```java @Component @Order(1) // 通过Spring的@Order注解定义执行顺序 public class ValidationHandler implements Handler<OrderRequest> { private Handler<OrderRequest> next; @Override public void handle(OrderRequest request) { if (request.getAmount() <= 0) throw new IllegalArgumentException("金额非法"); if (next != null) next.handle(request); // 传递请求 } @Override public void setNext(Handler<OrderRequest> next) { this.next = next; } } ``` - **责任链装配** 使用Spring的依赖注入自动装配处理器链: ```java @Configuration public class ChainConfig { @Autowired private List<Handler<OrderRequest>> handlers; @Bean public Handler<OrderRequest> orderHandlerChain() { for (int i = 0; i < handlers.size() - 1; i++) { handlers.get(i).setNext(handlers.get(i + 1)); } return handlers.get(0); } } ``` #### 2. 典型应用场景 若依框架中责任链模式的常见应用包括: 1. **多级权限校验** 例如:用户身份验证 → 数据权限校验 → 操作权限校验,形成链式校验[^3] 2. **工作流审批** 如报销审批流程:部门审批 → 财务审批 → 总经理审批 3. **日志处理管道** 日志格式处理 → 敏感信息过滤 → 持久化存储 #### 3. 使用注意事项 - **执行顺序控制** 使用`@Order`注解或自定义排序逻辑确保处理器顺序 - **异常处理机制** 需设计统一的异常阻断策略,避免请求在链中丢失 - **性能监控** 建议添加处理器执行时间统计,避免长链路导致的性能问题 #### 4. 扩展优化方向 - **动态配置支持** 通过数据库配置动态调整处理链节点 - **熔断机制** 对耗时较长的处理器设置超时中断 - **异步处理** 对非强顺序依赖的处理器采用并行执行 ```java // 客户端调用示例 @RestController public class OrderController { @Autowired private Handler<OrderRequest> orderHandler; @PostMapping("/create") public ResponseEntity<?> createOrder(@RequestBody OrderRequest request) { orderHandler.handle(request); // 触发责任链处理 return ResponseEntity.ok("订单创建成功"); } } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值