策略模式是对算法的包装,是把使用算法的责任和算法本身分割开来,委派给不同的对象管理,最终可以实现解决多重if判断问题。
定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的改变不会影响使用算法的客户
1.环境(Context)角色:持有一个Strategy的引用。
2.抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。
3.具体策略(ConcreteStrategy)角色:包装了相关的算法或行为。
比如 调用过多的第三方接口 处理同一业务。 如充值 支付宝、微信、银行等
则需要通过很多if来判断 通过策略模式解决多重if判断问题
1:抽象一个Strategy类 含共同特征方法
2:创建具体实现类 如支付宝、微信、银行的实现
3:创建一个得到bean对象的工具类 实现ApplicationContextAware 注解@Component
案例
自定义注解+策略模式 实现多仓库接口调用
1:自定义注解
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface HandlerWarehouseType {
int value();
}
2:抽象共同特征方法的接口
public interface WarehouseStrategy {
/**
* 仓库获取物流并更新
* @param a
* @return
* @throws Exception
*/
List<OrderApiConfirmVO> updateOrderExpTask(String a) throws Exception;
/**
* 仓库-订单推送
* @param a 参数
* @return
* @throws Exception
*/
List<OrderApiConfirmVO> updateOrderPush(String a) throws Exception;
}
3:具体业务实现类 实现接口
@Service
@Slf4j
@HandlerWarehouseType(12816) // 采用自定义注解
public class FwService implements WarehouseStrategy {
public List<OrderApiConfirmVO> updateOrderExpTask(String a) throws Exception{
//业务实现
}
public List<OrderApiConfirmVO> updateOrderPush(String a) throws Exception{
//业务实现
}
}
4:创建获取bean的工具类
@Component
public class HandlerWarehouseProcessor implements ApplicationContextAware {
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
// 获取自定义注解的类
Map<String, Object> mapClass=applicationContext.getBeansWithAnnotation(HandlerWarehouseType.class);
//根据key(注解的值) value(增加注解的类既实现类) 存储到map中
mapClass.forEach((k,v)->{
Class<WarehouseStrategy> warehouseStrategyClass =(Class<WarehouseStrategy>)v.getClass();
int type =warehouseStrategyClass.getAnnotation(HandlerWarehouseType.class).value();
HandlerWarehouseContext.wareHouseStrategyBeanMap.put(type,warehouseStrategyClass);
});
}
}
5:启动项目后从容器后获取bean 使调用者能通过抽象接口能获取到对应的bean 然后调用相应的实现
@Component
public class HandlerWarehouseContext {
@Autowired
private ApplicationContext applicationContext;
/**
* 存放所有策略类Bean的map
*/
public static Map<Integer, Class<WarehouseStrategy>> wareHouseStrategyBeanMap=new HashMap<>();
public WarehouseStrategy getWarehouseStrategy(Integer type){
Class<WarehouseStrategy> strategyClass = wareHouseStrategyBeanMap.get(type);
if(strategyClass==null){
throw new IllegalArgumentException("not found handler for type: " + type);
}
// 从容器中获取对应的策略Bean
return applicationContext.getBean(strategyClass);
}
}
6:调用
WarehouseStrategy warehouseStrategy = handlerWarehouseContext.getWarehouseStrategy(whProSourceEnum.getType());
// 具体要调用的方法
warehouseStrategy.updateOrderPush(platformApiConfig, cOrderLists, orderDetailList,
contactInfoVo, reduceStockMap)