策略模式前言咱们在这里不重复了,大家可以看我上上篇文章 策略模式之简单形式,上篇文章通过注解的形式解决类型分发,这次我们通过工厂模式,闲话少说,直接上代码
我们先建一个接口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接口,注入该类型,一种半自动化操作
上一篇注解策略模式见 注解方式