策略模式之工厂形式

策略模式前言咱们在这里不重复了,大家可以看我上上篇文章 策略模式之简单形式,上篇文章通过注解的形式解决类型分发,这次我们通过工厂模式,闲话少说,直接上代码

我们先建一个接口StockOperate类

public interface StockOperate {

    Boolean operate(WmsOperateStockParam wmsOperateStockParam);
}

因为利用到到里模版形式,所以创建一个抽象类BaseStockOperate,实现上述的接口

public abstract class BaseStockOperate implements StockOperate {

    //1、校验源货位编码必填
    protected abstract void validateToLocation(WmsOperateStockParam wmsOperateStockParam);

    //2、获取货位+sku锁
    protected abstract RLock getLocationLock(WmsOperateStockParam wmsOperateStockParam);

    //3、操作校验
    protected abstract void operateValidate(WmsOperateStockParam wmsOperateStockParam);

    //4、获得操作锁
    protected abstract RLock getLock(WmsOperateStockParam wmsOperateStockParam);

    //5、验证幂等
    protected abstract void repeatValidate(WmsOperateStockParam wmsOperateStockParam);

   //正在业务处理类,在子类中实现
    protected abstract Boolean operateStock(WmsOperateStockParam wmsOperateStockParam);

     //调用链
    @Override
    public Boolean operate(WmsOperateStockParam wmsOperateStockParam) {
        validateToLocation(wmsOperateStockParam);
        RLock locationLock = getLocationLock(wmsOperateStockParam);
        operateValidate(wmsOperateStockParam);
        RLock lock = getLock(wmsOperateStockParam);
        repeatValidate(wmsOperateStockParam);
        try {
            operateStock(wmsOperateStockParam);
        } catch (Exception e) {
            throw new BizException(WMSStockErrorCode.OPERATE_STOCK_ERROR.value(), WMSStockErrorCode.OPERATE_STOCK_ERROR.msg() + "/" + e.getMessage());
        } finally {
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
            if (locationLock.isHeldByCurrentThread()) {
                locationLock.unlock();
            }
        }
        return true;
    }
}

我们先创建一个工厂方法,用于保存每个类型的实现类StockOperateStrategyFactory,维护一个Map

public class StockOperateStrategyFactory {

    private static final Map<Integer, StockOperate> services = new ConcurrentHashMap<>();

    public static StockOperate getStockOperateByType(int type){
        StockOperate stockOperate = services.get(type);
        Assert.notNull(stockOperate,200010,"暂不支持该入库类型");
        return stockOperate;
    }

    public static void register(Integer operateType, StockOperate operate){
        Assert.notNull(operateType,200010,"operateType can't be null");
        services.put(operateType, operate);
    }
}

实现类,我们还是写一个入库上架 InboundStockOperate 继承上述的抽象类,且实现InitializingBean,用于向工厂类中注册该实现类

@Service
public class InboundStockOperate extends BaseStockOperate implements InitializingBean {

   //引用一些业务处理的service

    @Override
    protected Boolean operateStock(WmsOperateStockParam wmsOperateStockParam) {
        //写真正的业务逻辑
        return null;
    }

    @Override
    public void afterPropertiesSet() {
     StockOperateStrategyFactory.register(WmsOperateStockTypeEnum.INBOUND_HELVES.value(), this);
    }

接入方式

int stockType = 2;
//从工厂类map对象中获取
StockOperate stockOperate = StockOperateStrategyFactory.getStockOperateByType(stockType);
            stockOperate.operate(wmsOperateStock);

总结:

1、这种方式也是对于代码扩展性比较好,如果新增一种入库类型,只需要继承一个类,实现一个接口,注入该实现类即可

2、弊端是每次新增业务类型,都需要实现InitializingBean接口,注入该类型,一种半自动化操作

3、调用方需要先从工厂类中获取入库类型对应的实例对象,然后在调用对应的方法

上一篇注解策略模式见  注解方式

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值