Bootstrap

优惠券新增编辑代码优化之策略模式应用

概要

优化一次屎山代码

技术名词解释

策略模式

原来代码片

/**
     * 添加 可添加多条
     * 根据当前登录用户和店铺id,判断该用户是否用新增该店铺优惠券的权限
     * 根据不同的优惠方式,进行不同的必填校验
     *
     * @param couponInfoEntity
     */
    @ApiOperation(value = "优惠券-添加", notes = "优惠券-添加")
    @PostMapping(value = "/add")
    public Result<?> add(@RequestBody CouponInfoEntity couponInfoEntity) {
        AppLoginUser sysUser = (AppLoginUser) SecurityUtils.getSubject().getPrincipal();
        //先判断单个的信息,再检查批量信息
        if (StringUtils.isEmpty(couponInfoEntity.getShopId())) {
            return Result.error("未传入店铺id");
        } else {
            //判断当前用户是否是该店铺的著管理员。才有新增优惠券的权限,
            int roleflag = getRoleByuserIdAndShopId(sysUser.getId(), couponInfoEntity.getShopId());
            if (ROLE_TYPE_CYGLY == roleflag) {
                return Result.error("该用户为子管理员,无新增优惠券权限!");
            } else if (ROLE_TYPE_WBD == roleflag) {
                return Result.error("该用户与店铺没有绑定信息,无新增优惠券权限!");
            } else if (ROLE_TYPE_WXX == roleflag) {
                return Result.error("无法查询到该用户与店铺的绑定信息,无新增优惠券权限!");
            }
        }
        //商户类型
        if (StringUtils.isEmpty(couponInfoEntity.getCouponType())) {
            return Result.error("请选择商户类型");
        }
        //优惠方式
        if (StringUtils.isEmpty(couponInfoEntity.getCouponWay())) {
            return Result.error("请选择优惠方式");
        }
        //适用类型
        if (StringUtils.isEmpty(couponInfoEntity.getApplicableType())) {
            return Result.error("请至少选择一种适用类型");
        }
        //优惠时段
        if (null == couponInfoEntity.getStartTime() || null == couponInfoEntity.getEndTime()) {
            return Result.error("请选择优惠时段");
        } else {
            try {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
                couponInfoEntity.setStartTime(sdf.parse(sdf1.format(couponInfoEntity.getStartTime()) + " 00:00:00"));
                couponInfoEntity.setEndTime(sdf.parse(sdf1.format(couponInfoEntity.getEndTime()) + " 23:59:59"));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if (null == couponInfoEntity.getCouponInfoDetailList() || couponInfoEntity.getCouponInfoDetailList().size() < 1) {
            return Result.error("请填写优惠信息");
        }
        //遍历校验多条优惠券信息,如果没有问题,则直接添加,有问题则进行提示
        boolean flag = true;
        //错误信息
        List<String> errorMsgList = new ArrayList<>();
        //要新增的结果集
        List<CouponInfo> addList = new ArrayList<CouponInfo>();
        //遍历多条数据
        for (int i = 0; i < couponInfoEntity.getCouponInfoDetailList().size(); i++) {
            CouponInfo couponInfo = new CouponInfo();
            BeanUtils.copyProperties(couponInfoEntity, couponInfo);
            CouponInfoDetail detail = couponInfoEntity.getCouponInfoDetailList().get(i);
            if (YHFS_JM.equals(couponInfoEntity.getCouponWay())) {
                //判断减免优惠满、减免优惠减 两个字段是否都有值
                if (null == detail.getReductionFill() || null == detail.getReductionReduce()) {
                    return Result.error("请填写满减金额");
                } else if (detail.getReductionFill() <= detail.getReductionReduce()) {
                    return Result.error("满减金额不能大于等于总金额");
                } else if (detail.getReductionFill() < 0 || detail.getReductionReduce() < 0) {
                    return Result.error("金额不能小于0");
                } else {
                    couponInfo.setReductionFill(detail.getReductionFill());
                    couponInfo.setReductionReduce(detail.getReductionReduce());
                }
                //优惠方式 2 折扣
            } else if (YHFS_ZK.equals(couponInfoEntity.getCouponWay())) {
                if (null == detail.getDiscountStart() || null == detail.getDiscountEnd()) {
                    return Result.error("请填写折扣金额区间");
                } else if (detail.getDiscountStart() >= detail.getDiscountEnd()) {
                    return Result.error("折扣区间开始金额不能大于等于区间结束金额");
                } else if (detail.getDiscountStart() < 0 || detail.getDiscountEnd() < 0) {
                    return Result.error("金额不能小于0");
                } else {
                    couponInfo.setDiscountStart(detail.getDiscountStart());
                    couponInfo.setDiscountEnd(detail.getDiscountEnd());
                }
                if (null == detail.getDiscount()) {
                    return Result.error("请填写折扣");
                } else if (10 < detail.getDiscount()) {
                    return Result.error("折扣不能大于10");
                } else if (0 >= detail.getDiscount()) {
                    return Result.error("折扣不能小于等于0");
                } else {
                    couponInfo.setDiscount(detail.getDiscount());
                }
                //优惠方式 3 全免
            } else if (YHFS_QM.equals(couponInfoEntity.getCouponWay())) {
                if (null == detail.getFreeStart() || null == detail.getFreeEnd()) {
                    return Result.error("请填写全免金额区间");
                } else if (detail.getFreeStart() >= detail.getFreeEnd()) {
                    return Result.error("全免区间开始金额不能大于等于结束金额");
                } else {
                    couponInfo.setFreeStart(detail.getFreeStart());
                    couponInfo.setFreeEnd(detail.getFreeEnd());
                }
            }
            //发放总量
            if (null == detail.getProvideNum()) {
                return Result.error("请填写发放总量");
                //发放总量必须大于0
            } else if (0 >= detail.getProvideNum()) {
                return Result.error("优惠券发放总量必须大于0");
            } else {
                couponInfo.setProvideNum(detail.getProvideNum());
            }
            //单人限领
            if (null == couponInfoEntity.getReceiveNumPerPeople()) {
                return Result.error("请填写单人限领量");
                //判断单人限领量不能超过发放总量
            } else if (detail.getProvideNum() < couponInfoEntity.getReceiveNumPerPeople()) {
                return Result.error("单人限领量须小于发放总量");
            } else if (couponInfoEntity.getReceiveNumPerPeople() <= 0) {
                return Result.error("单人限领量须大于0");
            }
            addList.add(couponInfo);
        }
        if (flag) {
            //新增
            for (CouponInfo couponInfo : addList) {
                //组成优惠券名称
                String name = "";
                //优惠方式 1 减免
                if (YHFS_JM.equals(couponInfo.getCouponWay())) {
                    name = "满" + dealZero(couponInfo.getReductionFill()) + "减" + dealZero(couponInfo.getReductionReduce());
                    //优惠方式 2 折扣
                } else if (YHFS_ZK.equals(couponInfo.getCouponWay())) {
                    name = dealZero(couponInfo.getDiscountStart()) + "~" + dealZero(couponInfo.getDiscountEnd()) + "元" + dealZero(couponInfo.getDiscount()) + "折";
                    //优惠方式 3 全免
                } else if (YHFS_QM.equals(couponInfo.getCouponWay())) {
                    name = dealZero(couponInfo.getFreeStart()) + "~" + dealZero(couponInfo.getFreeEnd()) + "全免";
                }
                couponInfo.setCouponName(name);
                //是否上架
                //判断是否需要审核
                if (StringUtils.isNotEmpty(couponInfo.getUseRange())) {
                    //需要审核
                    couponInfo.setCheckState(CHECK_DSH);//待审核
                    //是否上架
                    if (IS_GROUND.equals(couponInfo.getIsGrounding())) {
                        //商户选择了上架,但是因为需要审核,所以修改状态为 待审核(上架) ,待审核通过后修改状态为上架
                        couponInfo.setIsGrounding(WAIT_IS_GROUND);
                    } else if (NO_GROUND.equals(couponInfo.getIsGrounding())) {
                        //商户选择了下架,但是因为需要审核,所以修改状态为 待审核(未上架) ,待审核通过后修改状态为下架
                        couponInfo.setIsGrounding(WAIT_NO_GROUND);
                    }
                } else {
                    couponInfo.setCheckState(CHECK_SHTG);//直接设置为审核通过
                    //判断是上架状态则更新该店铺的优惠券类型
                    if (IS_GROUND.equals(couponInfo.getIsGrounding())) {
                        couponInfoService.dealCouponNums(couponInfo.getShopId(), IS_GROUND, couponInfo.getCouponType(), couponInfo.getProvideNum());
                    }
                }
                couponInfo.setUseProvideNum(0);//已发放总量
                //新增后将优惠券库存存到redis中
                redisTemplate.opsForValue().set(COUPON_STOCK_NUM + couponInfo.getId(), couponInfo.getProvideNum());
                couponInfo.setDeleteStatus("0");//正常
                QueryWrapper<ShopUser> qq = new QueryWrapper();
                qq.eq("shop_id", couponInfoEntity.getShopId());
                qq.eq("app_user_id", sysUser.getId());
                ShopUser shopUser = shopUserService.getOne(qq);
                couponInfo.setShopUserId(shopUser.getId());
                if (IS_GROUND.equals(couponInfo.getIsGrounding())) {
                    couponInfo.setGiveOutTime(new Date());
                }
                couponInfoService.save(couponInfo);
            }
        } else {
            return Result.error("添加失败,请检查所填写的信息", errorMsgList);
        }
        return Result.ok("添加成功");
    }
/**
     * 编辑
     * @param couponInfo
     * @return
     */
    @ApiOperation(value = "优惠券-编辑", notes = "优惠券-编辑")
    @RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
    public Result<String> edit(@RequestBody CouponInfo couponInfo) {
        AppLoginUser sysUser = (AppLoginUser) SecurityUtils.getSubject().getPrincipal();
        if (StringUtils.isEmpty(couponInfo.getId())) {
            return Result.error("请传入要编辑的优惠券id!");
        }
        //判断必填字段是否校验
        //店铺id
        if (StringUtils.isEmpty(couponInfo.getShopId())) {
            return Result.error("请传入店铺id");
        } else {
            //判断当前用户是否是该店铺的著管理员。才有编辑优惠券的权限,
            int roleflag = getRoleByuserIdAndShopId(sysUser.getId(), couponInfo.getShopId());
            if (ROLE_TYPE_CYGLY == roleflag) {
                return Result.error("该用户为子管理员,无编辑优惠券权限!");
            } else if (ROLE_TYPE_WBD == roleflag) {
                return Result.error("用户与店铺没有绑定信息,无编辑优惠券权限!");
            } else if (ROLE_TYPE_WXX == roleflag) {
                return Result.error("无法查询到该用户与店铺的绑定信息,无编辑优惠券权限!");
            }
        }
        //商户类型
        if (StringUtils.isEmpty(couponInfo.getCouponType())) {
            return Result.error("请选择商户类型");
        }
        //优惠方式
        if (StringUtils.isEmpty(couponInfo.getCouponWay())) {
            return Result.error("请选择优惠方式");
            //判断不同优惠方式下需要填写的内容是否填写
            //优惠方式 1 减免金额
        } else if (YHFS_JM.equals(couponInfo.getCouponWay())) {
            //判断减免优惠满、减免优惠减 两个字段是否都有值
            if (null == couponInfo.getReductionFill() || null == couponInfo.getReductionReduce()) {
                return Result.error("请填写满减金额");
            } else if (couponInfo.getReductionFill() <= couponInfo.getReductionReduce()) {
                return Result.error("满减金额不能大于等于总金额!");
            }
            //优惠方式 2 折扣
        } else if (YHFS_ZK.equals(couponInfo.getCouponWay())) {
            if (null == couponInfo.getDiscountStart() || null == couponInfo.getDiscountEnd()) {
                return Result.error("请填写折扣金额区间!");
            } else if (couponInfo.getDiscountStart() >= couponInfo.getDiscountEnd()) {
                return Result.error("折扣区间开始金额不能大于等于区间结束金额!");
            }
            if (null == couponInfo.getDiscount()) {
                return Result.error("请填写折扣!");
            } else if (10 < couponInfo.getDiscount()) {
                return Result.error("折扣不能大于10");
            } else if (0 >= couponInfo.getDiscount()) {
                return Result.error("折扣不能小于等于0");
            }
            //优惠方式 3 全免
        } else if (YHFS_QM.equals(couponInfo.getCouponWay())) {
            if (null == couponInfo.getFreeStart() || null == couponInfo.getFreeEnd()) {
                return Result.error("请填写全免金额区间");
            } else if (couponInfo.getFreeStart() >= couponInfo.getFreeEnd()) {
                return Result.error("全免区间开始金额不能大于等于结束金额");
            }
        }
        //组成优惠券名称
        String name = "";
        //优惠方式 1 减免
        if (YHFS_JM.equals(couponInfo.getCouponWay())) {
            name = "满" + dealZero(couponInfo.getReductionFill()) + "减" + dealZero(couponInfo.getReductionReduce());
            //优惠方式 2 折扣
        } else if (YHFS_ZK.equals(couponInfo.getCouponWay())) {
            name = dealZero(couponInfo.getDiscountStart()) + "~" + dealZero(couponInfo.getDiscountEnd()) + "元" + dealZero(couponInfo.getDiscount()) + "折";
            //优惠方式 3 全免
        } else if (YHFS_QM.equals(couponInfo.getCouponWay())) {
            name = dealZero(couponInfo.getFreeStart()) + "~" + dealZero(couponInfo.getFreeEnd()) + "全免";
        }
        couponInfo.setCouponName(name);
        //适用类型
        if (StringUtils.isEmpty(couponInfo.getApplicableType())) {
            return Result.error("请至少选择一种适用类型");
        }
        //优惠时段
        if (null == couponInfo.getStartTime() || null == couponInfo.getEndTime()) {
            return Result.error("请选择优惠时段");
        } else {
            try {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
                couponInfo.setStartTime(sdf.parse(sdf1.format(couponInfo.getStartTime()) + " 00:00:00"));
                couponInfo.setEndTime(sdf.parse(sdf1.format(couponInfo.getEndTime()) + " 23:59:59"));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        //发放总量
        if (null == couponInfo.getProvideNum()) {
            return Result.error("请填写发放总量");
            //发放总量必须大于0
        } else if (0 >= couponInfo.getProvideNum()) {
            return Result.error("优惠券发放总量必须大于0");
        }
        //单人限领
        if (null == couponInfo.getReceiveNumPerPeople()) {
            return Result.error("请填写单人限领量");
            //判断单人限领量不能超过发放总量
        } else if (couponInfo.getProvideNum() < couponInfo.getReceiveNumPerPeople()) {
            return Result.error("单人限领量须小于发放总量");
        } else if (couponInfo.getReceiveNumPerPeople() <= 0) {
            return Result.error("单人限领量须大于0");
        }
        //是否上架
        //判断是否需要审核
        if (StringUtils.isNotEmpty(couponInfo.getUseRange())) {
            //需要审核
            couponInfo.setCheckState(CHECK_DSH);//待审核
            //是否上架
            if (IS_GROUND.equals(couponInfo.getIsGrounding())) {
                //商户选择了上架,但是因为需要审核,所以修改状态为 待审核(上架) ,待审核通过后修改状态为上架
                couponInfo.setIsGrounding(WAIT_IS_GROUND);
            } else if (NO_GROUND.equals(couponInfo.getIsGrounding())) {
                //商户选择了下架,但是因为需要审核,所以修改状态为 待审核(未上架) ,待审核通过后修改状态为下架
                couponInfo.setIsGrounding(WAIT_NO_GROUND);
            }
        } else {
            couponInfo.setCheckState(CHECK_SHTG);//直接设置为审核通过
            //判断是否有发放时间,没有则更新
            CouponInfo oldinfo = couponInfoService.getById(couponInfo.getId());
            if (null != oldinfo) {
                if (null != oldinfo.getGiveOutTime()) {
                    couponInfo.setGiveOutTime(oldinfo.getGiveOutTime());
                } else {
                    couponInfo.setGiveOutTime(new Date());
                }
            }
            //判断是上架状态的则更新redis该店铺优惠券总数
            if (IS_GROUND.equals(couponInfo.getIsGrounding())) {
                couponInfoService.dealCouponNums(couponInfo.getShopId(), IS_GROUND, couponInfo.getCouponType(), couponInfo.getProvideNum());
            }
        }
        couponInfoService.updateById(couponInfo);
        //编辑后,如修改优惠券总量,需同步修好redis
        if (redisTemplate.hasKey(COUPON_STOCK_NUM + couponInfo.getId())) {
            Integer couponNumOld = (Integer) redisTemplate.opsForValue().get(COUPON_STOCK_NUM + couponInfo.getId());
            if (couponNumOld != couponInfo.getProvideNum()) {
                redisTemplate.opsForValue().set(COUPON_STOCK_NUM + couponInfo.getId(), couponInfo.getProvideNum());
            }
        }
        return Result.OK("编辑成功!");
    }

代码全部逻辑都写在Controller中,判断逻辑混款。代码重复。健壮性差。后续扩展性差,如要增加优惠方式,后续会越来越混乱。

优化后代码如下:仅为记录

Controller

/**
     * 添加 可添加多条
     * 根据当前登录用户和店铺id,判断该用户是否用新增该店铺优惠券的权限
     * 根据不同的优惠方式,进行不同的必填校验
     * @param couponInfoEntity
     */
    @ApiOperation(value = "优惠券-添加", notes = "优惠券-添加")
    @PostMapping(value = "/add")
    public Result<?> add(@RequestBody CouponInfoEntity couponInfoEntity) {
        AppLoginUser sysUser = (AppLoginUser) SecurityUtils.getSubject().getPrincipal();
        if (sysUser == null) {
            return Result.error("<错误> token无效!");
        }
        //添加优惠券
        Result<?> addSuccess = couponInfoService.addCouponInfo(sysUser.getId(), couponInfoEntity);
        if (!addSuccess.isSuccess()) {
            log.error(addSuccess.getMessage());
            return addSuccess;
        }
        return Result.ok("添加成功");
    }
    /**
     * 编辑
     * @param couponInfo
     * @return
     */
    @ApiOperation(value = "优惠券-编辑", notes = "优惠券-编辑")
    @RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
    public Result<?> edit(@RequestBody CouponInfo couponInfo) {
        AppLoginUser sysUser = (AppLoginUser) SecurityUtils.getSubject().getPrincipal();
        if (sysUser == null) {
            return Result.error("<错误> token无效!");
        }
        //编辑优惠券
        Result<?> editSuccess = couponInfoService.editCouponInfo(sysUser.getId(), couponInfo);
        if (!editSuccess.isSuccess()) {
            log.error(editSuccess.getMessage());
            return editSuccess;
        }
        return Result.OK("编辑成功!");
    }

service

/**
     * 新增优惠券信息
     *
     * @param couponInfoEntity
     * @param userId
     * @return {@link Result }<{@link ? }>
     */
    Result<?> addCouponInfo(String userId, CouponInfoEntity couponInfoEntity);

    /**
     * 编辑优惠券信息
     *
     * @param userId
     * @param couponInfo
     * @return {@link Result }<{@link ? }>
     */
    Result<?> editCouponInfo(String userId, CouponInfo couponInfo);

serviceImpl

@Override
    public Result<?> addCouponInfo(String userId, CouponInfoEntity couponInfoEntity) {
        //判断当前用户是否是该店铺的著管理员。才有新增优惠券的权限,
        Result<?> validateUserRoleFlag = validateUserRoleFlag(userId, couponInfoEntity.getShopId());
        if (!validateUserRoleFlag.isSuccess()) {
            return validateUserRoleFlag;
        }
        // 校验数据完整性
        Result<?> validateRequiredFields = validateRequiredFields(couponInfoEntity);
        if (!validateRequiredFields.isSuccess()) {
            return validateRequiredFields;
        }
        try {
            Date startTime = DateUtils.LocalDateTime2Date(DateUtils.date2LocalDate(couponInfoEntity.getStartTime()).atStartOfDay());
            couponInfoEntity.setStartTime(startTime);
            Date endTime = DateUtils.LocalDateTime2Date(LocalDateTime.of(DateUtils.date2LocalDate(couponInfoEntity.getEndTime()), LocalTime.MAX));
            couponInfoEntity.setEndTime(endTime);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("处理优惠开始结束时间异常", e);
            return Result.error("处理优惠开始结束时间异常", e);
        }
        //遍历校验多条优惠券信息,如果没有问题,则直接添加,有问题则进行提示
        //要新增的结果集
        List<CouponInfo> couponInfoList = new ArrayList<>();
        //遍历多条数据
        for (int i = 0; i < couponInfoEntity.getCouponInfoDetailList().size(); i++) {
            CouponInfo couponInfo = new CouponInfo();
            CouponContext context = new CouponContext(couponInfoEntity.getCouponWay());
            //根据优惠方式检验优惠券的规则
            CouponInfoDetail detail = couponInfoEntity.getCouponInfoDetailList().get(i);
            detail.setReceiveNumPerPeople(couponInfoEntity.getReceiveNumPerPeople());
            Result<?> validationCouponRole = context.validate(detail);
            if (!validationCouponRole.isSuccess()) {
                validationCouponRole.setMessage("第" + (i + 1) + "条优惠券信息" + validationCouponRole.getMessage());
                return validationCouponRole;
            }
            BeanUtils.copyProperties(couponInfoEntity, couponInfo);
            BeanUtils.copyProperties(detail, couponInfo);
            //根据优惠方式,重新拼接优惠券名称
            String couponName = context.getCouponName(couponInfo);
            couponInfo.setCouponName(couponName);
            couponInfo.setCreateBy(userId);
            couponInfoList.add(couponInfo);
        }
        try {
            this.saveBatchCouponInfoList(couponInfoList);
        } catch (Exception e) {
            return Result.error("添加失败,请检查所填写的信息", e);
        }
        return Result.ok();
    }

    @Override
    public Result<?> editCouponInfo(String userId, CouponInfo couponInfo) {
        //判断当前用户是否是该店铺的主管理员。才有编辑优惠券的权限,
        Result<?> validateUserRoleFlag = validateUserRoleFlag(userId, couponInfo.getShopId());
        if (!validateUserRoleFlag.isSuccess()) {
            return validateUserRoleFlag;
        }
        if (org.parboiled.common.StringUtils.isEmpty(couponInfo.getId())) {
            return Result.error("请传入要编辑的优惠券id!");
        }
        // 校验数据完整性
        CouponInfoEntity couponInfoEntity = new CouponInfoEntity();
        BeanUtils.copyProperties(couponInfo, couponInfoEntity);
        CouponInfoDetail detail = new CouponInfoDetail();
        BeanUtils.copyProperties(couponInfo, detail);
        List<CouponInfoDetail> couponInfoDetailList = new ArrayList<>();
        couponInfoDetailList.add(detail);
        couponInfoEntity.setCouponInfoDetailList(couponInfoDetailList);
        Result<?> validateRequiredFields = validateRequiredFields(couponInfoEntity);
        if (!validateRequiredFields.isSuccess()) {
            return validateRequiredFields;
        }
        CouponContext context = new CouponContext(couponInfo.getCouponWay());
        Result<?> validationCouponRole = context.validate(detail);
        //根据优惠方式检验优惠券的规则
        if (!validationCouponRole.isSuccess()) {
            return validationCouponRole;
        }
        //根据优惠方式,重新拼接优惠券名称
        String couponName = context.getCouponName(couponInfo);
        couponInfo.setCouponName(couponName);
        //处理优惠开始结束时间
        try {
            Date startTime = DateUtils.LocalDateTime2Date(DateUtils.date2LocalDate(couponInfo.getStartTime()).atStartOfDay());
            couponInfo.setStartTime(startTime);
            Date endTime = DateUtils.LocalDateTime2Date(LocalDateTime.of(DateUtils.date2LocalDate(couponInfo.getEndTime()), LocalTime.MAX));
            couponInfo.setEndTime(endTime);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("编辑优惠券失败,原因:处理优惠开始结束时间异常", e);
            return Result.error("处理优惠开始结束时间异常", e);
        }
        //判断是否上架、是否需要审核
        this.checkStatus(couponInfo);
        couponInfoMapper.updateById(couponInfo);
        //编辑后,如修改优惠券总量,需同步修好redis
        redisTemplate.opsForValue().set(COUPON_STOCK_NUM + couponInfo.getId(), couponInfo.getProvideNum());
        return Result.ok();
    }
    private Result<?> validateUserRoleFlag(String userId, String shopId) {
        if (org.parboiled.common.StringUtils.isEmpty(shopId)) {
            return Result.error("未传入店铺id");
        }
        int roleFlag = this.getRoleByUserIdAndShopId(userId, shopId);
        if (ROLE_TYPE_CYGLY == roleFlag) {
            return Result.error("用户为子管理员,暂无权限!");
        } else if (ROLE_TYPE_WBD == roleFlag) {
            return Result.error("用户与店铺没有绑定,暂无权限!");
        } else if (ROLE_TYPE_WXX == roleFlag) {
            return Result.error("无法查询到用户信息,暂无权限!");
        }
        return Result.ok();
    }
    private Result<?> validateRequiredFields(CouponInfoEntity couponInfoEntity) {
        //商户类型
        if (org.parboiled.common.StringUtils.isEmpty(couponInfoEntity.getCouponType())) {
            return Result.error("请选择商户类型");
        }
        //优惠方式
        if (org.parboiled.common.StringUtils.isEmpty(couponInfoEntity.getCouponWay())) {
            return Result.error("请选择优惠方式");
        }
        //适用类型
        if (org.parboiled.common.StringUtils.isEmpty(couponInfoEntity.getApplicableType())) {
            return Result.error("请至少选择一种适用类型");
        }
        //优惠时段
        if (null == couponInfoEntity.getStartTime() || null == couponInfoEntity.getEndTime()) {
            return Result.error("请选择优惠时段");
        }
        //优惠信息
        if (null == couponInfoEntity.getCouponInfoDetailList() || couponInfoEntity.getCouponInfoDetailList().size() < 1) {
            return Result.error("请填写优惠信息");
        }
        return Result.ok();
    }
    private void saveBatchCouponInfoList(List<CouponInfo> couponInfoList) {
        for (CouponInfo couponInfo : couponInfoList) {
            //判断是否上架、是否需要审核
            this.checkStatus(couponInfo);
            //已发放总量
            couponInfo.setUseProvideNum(0);
            //正常
            couponInfo.setDeleteStatus("0");
            QueryWrapper<ShopUser> qq = new QueryWrapper();
            qq.eq("shop_id", couponInfo.getShopId());
            qq.eq("app_user_id", couponInfo.getCreateBy());
            ShopUser shopUser = shopUserMapper.selectOne(qq);
            couponInfo.setShopUserId(shopUser.getId());
            couponInfoMapper.insert(couponInfo);
            //新增后将优惠券库存存到redis中
            redisTemplate.opsForValue().set(COUPON_STOCK_NUM + couponInfo.getId(), couponInfo.getProvideNum());
        }
    }
    private void checkStatus(CouponInfo couponInfo) {
        if (org.parboiled.common.StringUtils.isNotEmpty(couponInfo.getUseRange())) {
            couponInfo.setCheckState(CHECK_DSH);//待审核
            if (IS_GROUND.equals(couponInfo.getIsGrounding())) {
                //商户选择了上架,但是因为需要审核,所以修改状态为 待审核(上架) ,待审核通过后修改状态为上架
                couponInfo.setIsGrounding(WAIT_IS_GROUND);
            } else if (NO_GROUND.equals(couponInfo.getIsGrounding())) {
                //商户选择了下架,但是因为需要审核,所以修改状态为 待审核(未上架) ,待审核通过后修改状态为下架
                couponInfo.setIsGrounding(WAIT_NO_GROUND);
            }
        } else {
            //直接设置为审核通过
            couponInfo.setCheckState(CHECK_SHTG);
            if (IS_GROUND.equals(couponInfo.getIsGrounding())) {
                couponInfo.setGiveOutTime(new Date());
                this.dealCouponNums(couponInfo.getShopId(), IS_GROUND, couponInfo.getCouponType(), couponInfo.getProvideNum());
            }
        }
    }

策略模式的上下文控制类

public class CouponContext {
    /**策略*/
    private CouponValidationStrategy strategy;
    public CouponContext(String couponWay) {
        switch (couponWay) {
            case YHFS_JM:
                strategy = new FullReductionStrategy();
                break;
            case YHFS_ZK:
                strategy = new DiscountStrategy();
                break;
            case YHFS_QM:
                strategy = new FreeStrategy();
                break;
            default:
                throw new IllegalArgumentException("未知的优惠方式: " + couponWay);
        }
    }
    public Result<?> validate(CouponInfoDetail detail) {
        if (detail.getProvideNum() == null) {
            return Result.error("请填写发放总量");
        } else if (detail.getProvideNum() <= 0) {
            return Result.error("优惠券发放总量必须大于0");
        }
        if (detail.getReceiveNumPerPeople() == null) {
            return Result.error("请填写单人限领量");
        } else if (detail.getProvideNum() < detail.getReceiveNumPerPeople()) {
            return Result.error("单人限领量须小于发放总量");
        } else if (detail.getReceiveNumPerPeople() <= 0) {
            return Result.error("单人限领量须大于0");
        }
        return strategy.validate(detail);
    }
    public String getCouponName(CouponInfo couponInfo) {
        return strategy.getCouponName(couponInfo);
    }
}

定义一个策略接口

public interface CouponValidationStrategy {
    /**
     * 定义一个优惠券校验策略的接口
     * @param detail
     * @return {@link Result }<{@link ? }>
     */
    Result<?> validate(CouponInfoDetail detail);

    /**
     * 处理优惠券名称
     * @param couponInfo
     * @return {@link String }
     */
    String getCouponName(CouponInfo couponInfo);
}

对应的策略实现

public class DiscountStrategy implements CouponValidationStrategy {
    private final int minDiscount = 0;
    private final int maxDiscount = 10;
    @Override
    public Result<?> validate(CouponInfoDetail detail) {
        if (detail.getDiscountStart() == null || detail.getDiscountEnd() == null) {
            return Result.error("请填写折扣金额区间");
        } else if (detail.getDiscountStart() >= detail.getDiscountEnd()) {
            return Result.error("折扣区间开始金额不能大于等于区间结束金额");
        } else if (detail.getDiscountStart() < 0 || detail.getDiscountEnd() < 0) {
            return Result.error("金额不能小于0");
        } else if (detail.getDiscount() == null) {
            return Result.error("请填写折扣");
        } else if (detail.getDiscount() > maxDiscount) {
            return Result.error("折扣不能大于10");
        } else if (detail.getDiscount() <= minDiscount) {
            return Result.error("折扣不能小于等于0");
        }
        return Result.ok();
    }

    @Override
    public String getCouponName(CouponInfo couponInfo) {
        return dealZero(couponInfo.getDiscountStart()) + "~" + dealZero(couponInfo.getDiscountEnd()) + "元"
                + dealZero(couponInfo.getDiscount()) + "折";
    }
}
public class FreeStrategy implements CouponValidationStrategy {
    @Override
    public Result<?> validate(CouponInfoDetail detail) {
        if (detail.getFreeStart() == null || detail.getFreeEnd() == null) {
            return Result.error("请填写全免金额区间");
        } else if (detail.getFreeStart() >= detail.getFreeEnd()) {
            return Result.error("全免区间开始金额不能大于等于结束金额");
        }
        return Result.ok();
    }

    @Override
    public String getCouponName(CouponInfo couponInfo) {
        return dealZero(couponInfo.getFreeStart()) + "~" + dealZero(couponInfo.getFreeEnd()) + "全免";
    }
}
public class FullReductionStrategy implements CouponValidationStrategy {
    @Override
    public Result<?> validate(CouponInfoDetail detail) {
        //判断减免优惠满、减免优惠减 两个字段是否都有值
        if (detail.getReductionFill() == null || detail.getReductionReduce() == null) {
            return Result.error("请填写满减金额");
        } else if (detail.getReductionFill() <= detail.getReductionReduce()) {
            return Result.error("满减金额不能大于等于总金额");
        } else if (detail.getReductionFill() < 0 || detail.getReductionReduce() < 0) {
            return Result.error("金额不能小于0");
        }
        return Result.ok();
    }

    @Override
    public String getCouponName(CouponInfo couponInfo) {
        return "满" + dealZero(couponInfo.getReductionFill()) + "减" + dealZero(couponInfo.getReductionReduce());
    }
}

优化后,代码逻辑清晰,结构层次分明,阅读性强。扩展性增强:如需增加优惠方式,只需增加一中新的优惠策略即可而不需要动业务代码,也可在使用优惠券时,对应的实付款金额计算也可在对应的策略中各自实现。

小结

策略模式替代大量ifelse的利器,一般是具有同类可替代的行为逻辑算法场景。比如;不同类型的交易方式(信用卡、支付宝、微信)、生成唯一ID策略(UUID、DB自增、DB+Redis、雪花算法、Leaf算法)等,都可以使用策略模式进行行为包装,供给外部使用。

;