经常在网上看到一些名为“别再if-else走天下了”,“教你干掉if-else”等之类的文章,大部分都会讲到用策略模式去代替if-else。策略模式实现的方式也大同小异。主要是定义统一行为(接口或抽象类),并实现不同策略下的处理逻辑(对应实现类)。客户端使用时自己选择相应的处理类,利用工厂或其他方式。
本文要说的是实现策略模式的一个方法,代替了传统的if-else判断。话不多说,直接上代码
首先创建一个策略接口
public interface StrategyService {
/**
* 选择使用的算法
* @param type 类型
* @return 策略算法
*/
Strategy render(String type);
}
然后实现这个service,构建策略
@Service
public class StrategyServiceImpl implements StrategyService {
private final Map<String, Strategy> strategyMap = new ConcurrentHashMap<>();
/**
* 构建策略信息
* @param strategyList 策略信息
*/
@Autowired
public StrategyServiceImpl(List<Strategy> strategyList) {
for(Strategy strategy : strategyList) {
if (strategy instanceof DeleteMaterialServiceImpl) {
strategyMap.put(InterfaceTypeEnum.deleteMaterial.getCode(), strategy);
}
if (strategy instanceof InsertMaterialServiceImpl) {
strategyMap.put(InterfaceTypeEnum.insertMaterial.getCode(), strategy);
}
if (strategy instanceof UpdateMaterialServiceImpl) {
strategyMap.put(InterfaceTypeEnum.updateMaterial.getCode(), strategy);
}
if (strategy instanceof MaterialInwareServiceImpl) {
strategyMap.put(InterfaceTypeEnum.materialInware.getCode(), strategy);
}
if (strategy instanceof MaterialOutwareServiceImpl) {
strategyMap.put(InterfaceTypeEnum.materialOutware.getCode(), strategy);
}
if (strategy instanceof AutoMaterialServiceImpl) {
strategyMap.put(InterfaceTypeEnum.autoMaterial.getCode(), strategy);
}
if (strategy instanceof InventoryStockServiceImpl) {
strategyMap.put(InterfaceTypeEnum.inventoryStock.getCode(), strategy);
}
}
}
@Override
public Strategy render(String type) {
return this.strategyMap.get(type);
}
}
其中 Strategy 是一个接口,根据不同的业务对Strategy得对实现
StrategyServiceImpl()方法是为了注入Strategy的实现类,根据类型匹配实现类
render(String type)方法是为了根据类型匹配带具体的实现类
Strategy接口
public interface Strategy {
AjaxResult materialInfoRomaToMes(MaterialRequestVo materialRequestVo) throws IllegalAccessException, IntrospectionException, InstantiationException;
AjaxResult materialInfoMesToRoma(MaterialRequestVo materialRequestVo);
}
然后简单扔出一个实现Strategy的例子
@Service
public class AutoMaterialServiceImpl implements Strategy {
@Override
@DSTransactional
public AjaxResult materialInfoRomaToMes(MaterialRequestVo materialRequestVo) {
String result = "";
return AjaxResult.success(result);
}
@Override
@RequiredLog(methodType="1")
public AjaxResult materialInfoMesToRoma(MaterialRequestVo materialRequestVo) {
return AjaxResult.success(result);
}
}
再一个接口多个实现都写好了之后,就是引用的问题了,下面看看如何利用render(String type)方法完成实现类的引用
@Service
public class MesProvideRomaServiceImpl {
@Autowired
private StrategyService strategyService;
@Override
@RequiredLog(methodType="2")
public AjaxResult materialInfoRomaToMes(MaterialRequestVo materialRequestVo) throws IllegalAccessException, IntrospectionException, InstantiationException {
return strategyService.render(materialRequestVo.getType()).materialInfoRomaToMes(materialRequestVo);
}
}
至此,到这里一个简单的策略模式就算是完成了,简单记录,也希望可以帮到有需要的人。