模板方法模式-项目中的使用

设计模式-总览icon-default.png?t=LBL2https://mp.csdn.net/mp_blog/creation/editor/122202507一、订单系统完成订单方法使用模板方法模式

1、背景介绍

发现线上和线下订单,其实逻辑都差不多,却写了两套差不多相同的东西。于是决定重构一下,方法如下:

@Transactional(rollbackFor = Exception.class)
    public void completeOrder(DanluOrderCompleteVO complete) {
        BusinessAsserts.notNull(complete, DepotNextDoorExceptions.Order.ILLEGAL_ERROR);
        BusinessAsserts.notBlank(complete.getOrderCode(), DepotNextDoorExceptions.Order.ILLEGAL_ERROR);
        String orderCode = complete.getOrderCode();
        Order order = orderRepository.findByOrderCode(orderCode);

        order.setStatus(OrderStatus.FINISHED);
        order.setCompleteTime(new Timestamp(System.currentTimeMillis()));
        try {
            orderRepository.save(order);
        } catch (Exception e) {
            logger.error("更新订单状态失败:{}", e);
            throw new DepotNextDoorException(500, "订单状态更新失败");
        }
    }
@Transactional(rollbackFor = Exception.class)
    public void completeOnlineOrder(CompleteOnlineOrderReqVO reqVO) {
        logger.info("订单确认收货:{}", JSON.toJSONString(reqVO));
        BusinessAsserts.notNull(reqVO, DepotNextDoorExceptions.Order.ILLEGAL_ERROR);
        Order order = null;
        if (Objects.nonNull(reqVO.getOrderId())) {
            order = orderRepository.findOne(reqVO.getOrderId());
        }
        if (StringUtils.isNotBlank(reqVO.getOrderCode())) {
            order = orderRepository.findByOrderCode(reqVO.getOrderCode());
        }
        BusinessAsserts.notNull(order, DepotNextDoorExceptions.Order.ORDER_NOT_EXIST);
        if(order.getStatus().equals(OrderStatus.DELIVERED) && 
!Objects.equals(order.getOrderChannel(), OrderChannelEnum.MANAGE)){
            try {
                order.setStatus(OrderStatus.FINISHED);
                order.setCompleteTime(new Timestamp(System.currentTimeMillis()));
                orderRepository.save(order);
                logger.info("已将订单状态调整为已完成:订单号:{}", reqVO.getOrderCode());
            } catch (Exception e) {
                logger.error("该订单完结状态更新异常", e);
            }
        } else {
            logger.error("该订单状态无法完结:请求信息:{}", JSON.toJSONString(reqVO));
        }
    }

2、分析

1、入参并不相同(历史原因不想改该部分),但是都只使用了订单编码查数据库订单信息,或者传入订单id或者编码

2、保存异常时处理方式却不同,分析应该是都打印日志,然后抛出异常进行回滚

3、不同之处就在获取订单后的验证,有一个需要验证订单渠道类型

4、分析模板步骤为:1)、打印日志;2)、验证参数(可进行省略);3)、获取订单并进行验证;4)、验证订单状态(相同的        部分放父类);5、持久化修改订单状态

3、重构

于是重构后 父模板类,validCompleteOrder方法是唯一不同的处理部分,使用空方法让子类重新,如下:

/**
 *  完成订单模板
 *
 * @param orderId 订单id
 * @param orderCode 订单编码
 */
public final void completeOrder(Long orderId, String orderCode) {
    // 1、打印日志
    logger.info("订单确认收货: orderId:{},orderCode:{}", orderId, orderCode);
    // 2、验证参数(可进行省略)
    // 3、获取订单
    Order order = null;
    if (Objects.nonNull(orderId)) {
        order = orderRepository.findOne(orderId);
    }
    if (StringUtils.isNotBlank(orderCode)) {
        order = orderRepository.findByOrderCode(orderCode);
    }
    // 4、验证订单状态(相同的部分放父类)
    BusinessAsserts.notNull(order, DepotNextDoorExceptions.Order.ORDER_NOT_EXIST);
    BusinessAsserts.isTrue(Objects.equals(OrderStatus.DELIVERED, order.getStatus()), 
        DepotNextDoorExceptions.Order.ORDER_STATUS_CAN_NOT_COMPLETE);
    validCompleteOrder(order.getOrderChannel());
    // 5、保存订单信息
    order.setStatus(OrderStatus.FINISHED);
    order.setCompleteTime(new Timestamp(System.currentTimeMillis()));
    try {
        orderRepository.save(order);
        logger.info("已将订单状态调整为已完成:订单号:{}", order.getOrderCode());
    } catch (Exception e) {
        logger.error("该订单完结状态更新异常", e);
        throw new DepotNextDoorException(500, "订单状态更新失败");
    }
}

/**
 *  验证订单状态和信息,子类必须实现
 */
protected void validCompleteOrder(OrderChannelEnum channelEnum) {

}

子类重构后为:

@Override
@Transactional(rollbackFor = Exception.class)
public void completeOnlineOrder(CompleteOnlineOrderReqVO reqVO) {
    BusinessAsserts.notNull(reqVO, DepotNextDoorExceptions.Order.ILLEGAL_ERROR);
    super.completeOrder(reqVO.getOrderId(), reqVO.getOrderCode());
}

@Override
protected void validCompleteOrder(OrderChannelEnum channelEnum) {
    BusinessAsserts.isTrue(OrderChannelEnum.MANAGE.equals(channelEnum), 
        DepotNextDoorExceptions.Order.ORDER_STATUS_CAN_NOT_COMPLETE);
}

@Override
@Transactional(rollbackFor = Exception.class)
public void completeOrder(DanluOrderCompleteVO complete) {
    super.completeOrder(null, complete.getOrderCode());
}

后续再添加 项目中使用的例子,一个设计模式就是多用几次,穷举,就知道了。个人理解

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值