策略模式与SPI机制异同

策略模式

策略模式解决的痛点是多个if else 进行条件判断从而处理不同的逻辑,提高代码的可维护性、
可扩展性、可读性。
策略模式的逻辑
1、创建一个最上层的策略接口,定义策略的方法

//此接口定义策略类的公共方法
interface Categry(){
     TypeEnum  getType(); //获取策略的类型
     Result  doProcess(); //各策略类的实现的正式逻辑
}

2、创建各自的策略类,实现策略接口和对应的方法

策略类A
class CategryA implements(){
    //获取策略的类型
    TypeEnum  getType(){
           //TODO     
        } 
      //各策略类的实现的正式逻辑
    Result  doProcess();{
          //TODO
       }
}

//////////////////////////////////
策略类B
class CategryB implements(){
        //获取策略的类型
        TypeEnum  getType(){
           //TODO     
        } 
       //各策略类的实现的正式逻辑
       Result  doProcess();{
          //TODO
        }
}

3、将所有策略类注入到内存中(可以通过工厂模式 或者spring的方式去注入),并且实现根据类型获取策略类的方法

下面是使用spring的方式去注入保存各个策略类

class xxxxManager() implements InitializingBean,ApplicationContextAware{
    private static final Map processCollections = new ConcurrentHashMap<>();
    private ApplicationContext appContext;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
      appContext = applicationContext;
    }
   
    @Override
    public void afterPropertiesSet() {
        // 将 Spring 容器中所有的 Payment 接口实现类注册到 processCollections
        appContext.getBeansOfType(Categry.class)
                  .values()
                  .forEach(categry-> processCollections.put(categry.getType(), categry));
    }
  
   public static Categry getCategry(TypeEnum type) {
        if (type== null) {
            throw new IllegalArgumentException("type is empty.");
        }
        if (!processCollections.containsKey(type)) {
            throw new IllegalArgumentException("type not supported.");
        }
        return processCollections.get(type);
    }

}

4、客户端使用策略类

Categry  aaa = xxxxManager.getCategry(type);
aaa.doProcess();

策略模式与SPI机制的区别

思想都类似,都是将后续的扩展与原来的代码隔离开来,从而避免新增代码对原有代码的影响
1、策略模式应用与同一个项目中代码层面,类层次,属于类级别的隔离
SPI机制更多的是链接不同项目,应用于框架级别,属于框架级别的隔离
2、SPI需要通过配置文件META-INF/services/xxx.yml下配置各个类的全限定类名

com.xxx.xxx.CategryA
com.xxx.xxx.CategryB

SPI获取类的方式

ServiceLoader.load(xxx.class);

你可能感兴趣的:(策略模式与SPI机制异同)