工厂模式+模板方法模式,实现步骤相同地订单逻辑

一、定义工厂管理类

/**
 * 订单业务管理类
 * @author yunpeng.zhao
 * @version $Id PayMethodManager.java, v 0.1 2018-02-04 上午11:03 yp-tc-m-2651 Exp $$
 */
public class OrderBizFactory {

    private static final Logger logger = LoggerFactory.getLogger(OrderBizFactory.class);

    private static Map<String,OrderBiz> payBizMap = new ConcurrentHashMap<String, OrderBiz>();



    /**
     * 得到订单实例
     * @param orderType
     * @return
     */
    public static OrderBiz getOrderBiz(OrderTypeEnum orderType){
        try {
            if (orderType !=null){
                return payBizMap.get(orderType.name());
            }else {
                logger.warn("订单类型为空,无法获取订单实例");
                throw BalanceGrowException.ORDER_GET_ORDER_BIZ_EXCEPTION;
            }

        } catch (Exception e) {
            logger.error("获取支付业务类出现异常:{}",e);
            throw BalanceGrowException.ORDER_GET_ORDER_BIZ_EXCEPTION;
        }
    }

    /**
     * 提供的对外接口,以方便运行时添加
     * @param payBiz
     * @param payBiz
     */
    public static void addOrderBizService(String payBiz,OrderBiz orderBiz){
        payBizMap.put(payBiz,orderBiz);
    }
}

二、抽象出处理接口

public interface OrderBiz {
    /**
     * 订单处理入口,增加redis并发请求锁
     * @param requestBean
     * @return
     */
    OrderResponseBean process(final OrderRequestBean requestBean) ;


    /**
     * 异步回调处理入口
     * @param callbackParam
     * @return
     */
    BaseResponseDTO callback(Map callbackParam);

}

三、定义步骤地模板方法抽象类

/**
 * 订单请求处理类
 * @author yunpeng.zhao
 */
public abstract class AbstractOrderBiz implements OrderBiz {
    private static Logger logger = LoggerFactory.getLogger(AbstractOrderBiz.class);

    @Autowired
    private AccountInfoService accountInfoService;


    /**
     * 订单业务请求处理入口
     * @param requestBean
     */
    @Override
    public OrderResponseBean process(final OrderRequestBean requestBean)  {
        OrderResponseBean orderResponseBean = new OrderResponseBean();

        //1.加锁
        //防并发redisKey
        RedisLock redisLock = createRedisLock(requestBean);
        try {
            if (redisLock.lock()) {
                //校验订单
                checkOrder(requestBean);
                //2.校验账户
                checkAccount(requestBean);
                //3.创建记录
                addOrder(requestBean);
            }else {
                logger.info("订单请求未获取到redis锁,业务方请求号:{}",requestBean.getRequestFlowNo());
            }
        } catch (BalanceGrowException e) {
            throw e;
        }  finally{
            redisLock.unlock();
        }

        orderProcess(requestBean,orderResponseBean);

        //是否通知业务方
        boolean isNeedCallBack = isNeedCallback(requestBean);
        if(isNeedCallBack){
            //异步通知业务方
            asyncCallBack(requestBean);
        }

        return orderResponseBean;
    }

    /**
     * 是否异步通知业务方
     * @return
     */
    protected  boolean isNeedCallback(OrderRequestBean requestBean){
        //默认实现不回调
        return false;
    }
    /**
     * 银行订单异步回调处理入口
     * @param callbackParam
     * @return
     */
    @Override
    public BaseResponseDTO callback(Map callbackParam) {
        BaseResponseDTO responseDTO = new BaseResponseDTO("0001","回调失败");
        OrderRequestBean orderRequestBean = new OrderRequestBean();
        //资金流水号
        String fundFlowNo = (String)callbackParam.get("tran_no");
        //1.校验交易订单是否已经成功
        boolean isReturn = checkOrderByCallback(orderRequestBean,fundFlowNo,responseDTO);

        if (isReturn){
            return responseDTO;
        }

        //2.更新订单
        updateOrderByCallback(orderRequestBean,callbackParam,responseDTO);

        return responseDTO;
    }

    /**
     * 当订单状态不为成功时
     * 更新银行异步回调的订单
     * @param orderRequestBean
     * @param callbackParam
     * @param responseDTO
     */
    protected abstract void updateOrderByCallback(OrderRequestBean orderRequestBean, Map callbackParam, BaseResponseDTO responseDTO);

    /**
     * 校验异步回调的订单是否成功,
     * 不成功时,将订单放到OrderRequestBean中,供后续更新
     * @param orderRequestBean
     * @param fundFlowNo
     * @return
     */
    protected abstract boolean checkOrderByCallback(OrderRequestBean orderRequestBean, String fundFlowNo,BaseResponseDTO responseDTO);


    /**
     * 创建redis锁
     * @param requestBean
     * @return
     */
    private RedisLock createRedisLock(OrderRequestBean requestBean) {
        return new RedisLock(BalanceGrowConstant.REDIS_KEY_PREFIX_CONSTANTS_ORDER
                +requestBean.getBizSystem()+requestBean.getRequestFlowNo());
    }

    /**
     * 校验订单是否存在
     * @param requestBean
     */
    protected abstract void checkOrder(OrderRequestBean requestBean);

    /**
     * 校验虚拟账户是否存在
     * @param requestBean
     */
    protected abstract void checkAccount(OrderRequestBean requestBean);

    /**
     * 创建不同类型的交易订单
     * @param requestBean
     */
    protected abstract void addOrder(OrderRequestBean requestBean);

    /**
     * 处理不同类型的交易订单,
     * 调用银行不同的接口
     * @param requestBean
     */
    protected abstract void orderProcess(OrderRequestBean requestBean,OrderResponseBean orderResponseBean);

    /**
     * 异步化处理通知业务方
     * 只有成功、失败地订单才回调
     * @param requestBean
     */
    public abstract void asyncCallBack(OrderRequestBean requestBean);
    /**
     * 校验虚拟账户是否存在
     * @param accountNo
     */
    protected AccountInfoEntity queryAccount(String accountNo) {

        //2.校验账户是否存在
        AccountInfoEntity accountInfoEntity =accountInfoService.queryByAccountNo(accountNo);
        if(accountInfoEntity == null){
            logger.warn("虚拟账户:{}不存在!",accountNo);
            throw BalanceGrowException.ORDER_ACCOUNT_IS_NOT_EXIST_EXCEPTION;
        }

        return accountInfoEntity;
    }

}

四、子类只需要继承并实现具体地处理步骤,就行,从而处理不同类型地订单

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值