这段代码是使用建造者模式(Builder Pattern)来构建一个 AiServices 实例 ,专门用于处理 VUE_PROJECT 这个业务场景下的 AI 服务。它通过链式调用的方式,一步步配置 AI 服务所需的核心组件和策略,最终构建出可用的服务对象。
逐行拆解:
java
运行
case VUE_PROJECT -> AiServices.builder(AiCodeGeneratorService.class)
// 1. 设置流式对话模型(核心AI推理模型)
.streamingChatModel(reasoningStreamingChatModel)
// 2. 设置对话记忆提供器(根据memoryId获取对话上下文)
.chatMemoryProvider(memoryId -> chatMemory)
// 3. 注册可用的工具(这里是文件写入工具)
.tools(new FileWriteTool())
// 4. 设置工具名称幻觉策略(处理AI调用不存在工具的情况)
.hallucinatedToolNameStrategy(toolExecutionRequest -> ToolExecutionResultMessage.from(
toolExecutionRequest, "Error: there is no tool called " + toolExecutionRequest.name()
))
// 5. 完成构建,返回最终的AiServices实例
.build();
核心功能总结:
- 针对
VUE_PROJECT场景,构建一个具备「流式对话、上下文记忆、文件写入工具、错误兜底策略」的 AI 代码生成服务。 - 每个链式调用的方法都是在给建造者对象设置不同的配置项,最终通过
build()完成对象创建。
二、建造者模式(Builder Pattern)核心讲解
建造者模式是一种创建型设计模式 ,核心解决的问题是:当一个对象的构造参数 / 配置项过多、或者构造逻辑复杂时,避免出现「构造方法参数爆炸」或「对象状态不一致」的问题。
1. 建造者模式的核心角色
表格
| 角色 | 说明 | 对应代码中的实现 |
|---|---|---|
| 产品(Product) | 最终要创建的复杂对象 | AiServices(或 AiCodeGeneratorService) |
| 建造者(Builder) | 定义构建产品的各个步骤,持有产品的半成品 | AiServices 内部的 Builder 类(隐式) |
| 导演(Director) | 可选,指挥建造者按顺序构建(这里省略,直接由调用者控制) | 调用方(这段代码本身) |
2. 建造者模式的优势(为什么不用普通构造方法)
如果不用建造者模式,你可能需要这样写:
java
运行
// 弊端:参数多、顺序易乱、可选参数需要重载多个构造方法
AiServices aiService = new AiServices(AiCodeGeneratorService.class,
reasoningStreamingChatModel,
chatMemory,
new FileWriteTool(),
hallucinatedToolNameStrategy);
而建造者模式的优势:
- 可读性高 :每个配置项都有明确的方法名(如
.streamingChatModel()),一眼能看懂配置的是什么。 - 灵活性强 :支持可选配置(比如可以不设置
hallucinatedToolNameStrategy,建造者会用默认值)。 - 对象状态一致 :只有调用
build()时才会创建最终对象,避免创建出半成品。
三、为什么能实现链式调用?
链式调用的底层原理非常简单:建造者的每个配置方法(如 streamingChatModel())执行完配置后,都会返回「建造者对象本身(this)」。
1. 底层实现逻辑(模拟)
我们可以模拟 AiServices.Builder 的核心代码,你就能明白:
java
运行
// 模拟AiServices的内部建造者类
public static class Builder {
// 持有产品的配置项(半成品)
private Class<?> serviceClass;
private StreamingChatModel streamingChatModel;
private Function<String, ChatMemory> chatMemoryProvider;
private List<Tool> tools = new ArrayList<>();
private Function<ToolExecutionRequest, ToolExecutionResultMessage> hallucinatedToolNameStrategy;
// 1. 初始化建造者(对应builder()方法)
public static Builder builder(Class<?> serviceClass) {
Builder builder = new Builder();
builder.serviceClass = serviceClass;
return builder; // 返回建造者对象
}
// 2. 配置流式对话模型,返回this(建造者本身)
public Builder streamingChatModel(StreamingChatModel model) {
this.streamingChatModel = model;
return this; // 关键:返回自己,才能继续链式调用
}
// 3. 配置对话记忆提供器,返回this
public Builder chatMemoryProvider(Function<String, ChatMemory> provider) {
this.chatMemoryProvider = provider;
return this;
}
// 4. 其他配置方法同理...
public Builder tools(Tool tool) {
this.tools.add(tool);
return this;
}
public Builder hallucinatedToolNameStrategy(Function<ToolExecutionRequest, ToolExecutionResultMessage> strategy) {
this.hallucinatedToolNameStrategy = strategy;
return this;
}
// 5. 最终构建方法,返回产品对象
public AiServices build() {
// 校验配置、创建最终的AiServices实例
return new AiServices(this);
}
}
2. 链式调用的执行流程
plaintext
AiServices.builder(...) → 返回Builder对象
.streamingChatModel(...) → 配置属性,返回同一个Builder对象
.chatMemoryProvider(...) → 配置属性,返回同一个Builder对象
.tools(...) → 配置属性,返回同一个Builder对象
.hallucinatedToolNameStrategy(...) → 配置属性,返回同一个Builder对象
.build() → 最终创建并返回AiServices对象
简单说:每一步调用都是在给同一个 Builder 对象设置属性,并且每一步都返回这个对象,所以可以一直「点」下去。
总结
- 这段代码的核心:通过建造者模式构建一个配置完整的 AI 服务实例,针对 VUE_PROJECT 场景配置了流式模型、记忆功能、文件工具和错误策略。
- 建造者模式的核心:将复杂对象的「构建步骤」和「最终创建」分离,解决多参数构造的可读性、灵活性问题。
- 链式调用的原理 :建造者的每个配置方法都返回
this(建造者自身),使得调用可以连续串联。
建造者模式在实际开发中非常常见(比如 Java 的 StringBuilder、MyBatis 的 SqlSessionFactoryBuilder、Spring 的 BeanDefinitionBuilder),核心思想都是「分步配置、统一构建」,而链式调用则是让这个过程更优雅的语法糖。