Builder Pattern

这段代码是使用建造者模式(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 对象设置属性,并且每一步都返回这个对象,所以可以一直「点」下去

总结

  1. 这段代码的核心:通过建造者模式构建一个配置完整的 AI 服务实例,针对 VUE_PROJECT 场景配置了流式模型、记忆功能、文件工具和错误策略。
  2. 建造者模式的核心:将复杂对象的「构建步骤」和「最终创建」分离,解决多参数构造的可读性、灵活性问题。
  3. 链式调用的原理 :建造者的每个配置方法都返回 this(建造者自身),使得调用可以连续串联。

建造者模式在实际开发中非常常见(比如 Java 的 StringBuilder、MyBatis 的 SqlSessionFactoryBuilder、Spring 的 BeanDefinitionBuilder),核心思想都是「分步配置、统一构建」,而链式调用则是让这个过程更优雅的语法糖。

相关推荐
禾小西9 分钟前
Spring AI :Spring AI的介绍
java·人工智能·spring
ybwycx18 分钟前
springboot之集成Elasticsearch
spring boot·后端·elasticsearch
qqty121742 分钟前
springboot+mybaties项目中扫描不到@mapper注解的解决方法
java·spring boot·mybatis
星辰_mya1 小时前
InnoDB的“身体结构”:页、Buffer Pool与Redo Log的底层奥秘
数据库·mysql·spring·面试·系统架构
吾日三省Java3 小时前
SpringBoot锁设计:让你的系统不再“抢”出问题!
java·spring boot·设计思路
代码探秘者3 小时前
【算法】吃透18种Java 算法快速读写模板
数据结构·数据库·python·算法·spring
java1234_小锋3 小时前
Java高频面试题:谈谈你对SpringBoot的理解?
java·开发语言·spring boot
空空潍3 小时前
Spring AI 实战系列(三):多模型共存+双版本流式输出
java·人工智能·spring
彭于晏Yan3 小时前
SpringBoot整合ECC实现文件签名与验签
java·spring boot·后端
pupudawang3 小时前
Spring EL 表达式的简单介绍和使用
java·后端·spring