策略模式之工厂形式

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

我们先建一个接口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);
    }

总结:

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

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

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

上一篇:天干地支


下一篇:[SUCTF 2019]CheckIn 1