项目里接了多个第三方 SDK 后,如何使用适配器模式+策略模式优化?(Adapter + Strategy)

文章目录

一、问题

当一个系统需要同时接入多个第三方 SDK,而这些 SDK:

能力相似(功能重合)

接口不一致(方法、参数、返回值都不同)

未来还可能继续扩展

如果在业务层直接使用它们,代码通常会变成这样

java 复制代码
if (type == A) {
    // 调 A 的 SDK
} else if (type == B) {
    // 调 B 的 SDK
}

这是一种糟糕的处理方法,每次随着新增一种SDK 都需要去调整对应的if else 代码 导致大量的嵌套循环。

本文将以实际的例子 去讲解 如何使用适配器模式+ 策略者模式

去优化如此冗长的代码。

将以spring ai 引入 aiyun dashScope 的SDK

以及 引入 openAi SDK为例子 去讲解。

二、先解决第一个问题:接口不统一(Adapter)

目标

让业务层只面对一种"能力接口",而不是多个 SDK。

做法

定义一个统一的适配器接口,抽象出业务真正关心的能力:

java 复制代码
public interface AIModelAdapter {

    String getModelId();

    boolean isEnabled();

    String chat(List<Map<String, String>> messages);

    Flux<String> stream(List<Map<String, String>> messages);

    float[] embed(String text);
}

各个 SDK 各自实现适配器

java 复制代码
public class AliyunAdapter implements AIModelAdapter {
    @Override
    public String chat(...) {
        // 阿里云 SDK 调用细节
    }
}
java 复制代码
public class OpenAIAdapter implements AIModelAdapter {
    @Override
    public String chat(...) {
        // OpenAI SDK 调用细节
    }
}

最终实现:

屏蔽 SDK 差异

统一调用方式

新增 SDK 只需新增 Adapter

业务代码不再直接依赖第三方库

三、第二个问题:Adapter 多了,用哪个?(Strategy)

Adapter 解决了"怎么用 SDK",但没解决"用哪一个"。

如果继续在业务层写判断:

java 复制代码
if (modelId.equals("aliyun")) {
    return aliyunAdapter;
}

本质上还是 if-else,只是换了个地方。

四、把"选择逻辑"集中管理(Strategy Router)

核心原则

选择逻辑必须集中,不能散落在业务代码中。

策略仓库:集中管理所有 Adapter

java 复制代码
public class ModelRegistry {

    private final Map<String, AIModelAdapter> adapters = new HashMap<>();

    public Optional<AIModelAdapter> get(String modelId) {
        return Optional.ofNullable(adapters.get(modelId));
    }

     /**
     * 注册模型适配器
     */
    public void register(AIModelAdapter adapter) {
        adapters.put(adapter.getModelId(), adapter);
        log.info("Registered AI model adapter: {} ({}), enabled: {}", 
                adapter.getModelName(), adapter.getModelId(), adapter.isEnabled());
    }
}

策略路由器:只负责"选哪一个"

java 复制代码
public class ModelRouter {

    ModelRegistry

    public AIModelAdapter route(Long userId) {

			//	ModelRegistry.get()
			//	根据user的选择 从 ModelRegistry 的map中返回可用的模型 adapter
        return selectedAdapter;
    }
}

五、最终调用方式

业务层最终只剩下这两行:

java 复制代码
AIModelAdapter adapter = modelRouter.route(userId);
adapter.chat(messages);

六、这种组合在哪些业务场景特别常见?

支付渠道(支付宝 / 微信 / 银联)

短信服务(多云厂商)

对象存储(OSS / S3 / MinIO)

风控规则 / 排序策略

AI 模型 / 算法切换

只要你看到:

"可能还会再接一家"

"需要按条件选择实现"

这套结构几乎一定用得上。

七、更多的源码:Spring Cache:如何把 Redis / Caffeine / Ehcache 适配成同一套 Cache API

适配器接口:org.springframework.cache.Cache

这是真正的核心接口(简化后):

java 复制代码
public interface Cache {

    String getName();

    Object getNativeCache();

    ValueWrapper get(Object key);

    void put(Object key, Object value);

    void evict(Object key);

    void clear();
}

具体适配器:Redis / Caffeine / Ehcache
Redis 的适配器(简化结构)

java 复制代码
public class RedisCache implements Cache {

    private final RedisOperations redisOperations;

    @Override
    public ValueWrapper get(Object key) {
        Object value = redisOperations.opsForValue().get(key);
        return (value != null ? () -> value : null);
    }

    @Override
    public void put(Object key, Object value) {
        redisOperations.opsForValue().set(key, value);
    }
}

Caffeine 的适配器(简化)

java 复制代码
public class CaffeineCache implements Cache {

    private final com.github.benmanes.caffeine.cache.Cache<Object, Object> cache;

    @Override
    public ValueWrapper get(Object key) {
        Object value = cache.getIfPresent(key);
        return (value != null ? () -> value : null);
    }

    @Override
    public void put(Object key, Object value) {
        cache.put(key, value);
    }
}

你可以清楚看到:

Redis 用的是 RedisOperations

Caffeine 用的是 cache.getIfPresent

但对外暴露的永远是 Cache 接口

相关推荐
程序员良辰2 小时前
JDK 环境变量的核心作用 ? 如果使用 IDEA 运行程序,是否可以不配置环境变量 ?
java·开发语言·intellij-idea
悟能不能悟2 小时前
eclipse run springboot的application类,保存文件的路径会默认在哪里
java·spring boot·eclipse
独自破碎E2 小时前
【数组】分糖果问题
java·开发语言·算法
没有bug.的程序员2 小时前
Spring Boot 性能优化:启动时间从 5s 到 1s 的全链路实战指南
java·spring boot·后端·spring·性能优化·全链路·启动时间
10岁的博客2 小时前
C语言造轮子大赛
java·c语言·数据结构
草履虫建模2 小时前
A01 开发环境与第一个 Java 程序(IDEA / JDK / Maven 基础)
java·spring·jdk·maven·intellij-idea·idea·基础
yaoxin5211232 小时前
305. Java Stream API - 短路操作
java·开发语言
Sweet锦2 小时前
无需JVM!GraalVM打造Windows平台零依赖Java应用
java·windows·后端·云原生·开源