策略模式与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<ProcessNameSpaceEnum, Process> 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);
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容