找回密码
 立即注册
首页 业界区 科技 AI编程在OOP场景下探索

AI编程在OOP场景下探索

敖雨燕 2025-6-30 01:38:22
AI编程在OOP场景下探索<br><br>背景<br><br>     我们Spring AI工程引用代码如下,由于基于Mock单元测试下ChatClient总是为空,异常是<br>Cannot invoke "org.springframework.ai.chat.client.ChatClient.prompt(String)" because "this.chatClient" is null<br>     Spring AI 1.0.0的正式发布时间为2025年5月20日<br>业务逻辑代码<br><br>@Service<br>public class TaskMcpCallServerServices implements AiService, ChatService {<br>private final ChatClient chatClient;<br>    /**<br>     * Constructs a new TaskMcpCallServerServices instance.<br>     * @param aiClientBuilder the ChatClient builder used to create the chat client<br>     */<br>public TaskMcpCallServerServices(ChatClient.Builder chatClientBuilder) {<br>this.chatClient = chatClientBuilder.build();<br>    }<br>    @Override<br>public ChatClient getChatClient() {<br>return chatClient;<br>    }<br>    @Override<br>    /**<br>     * Gets AI response for the given prompt by calling the MCP server.<br>     * @param prompt the input prompt to send to the AI<br>     * @return ResponseEntity containing the AI response<br>     */<br>public ResponseEntity getAiResponse(String prompt) {<br>String response = this.chatClient<br>                .prompt(prompt)<br>                .call()<br>                .content();<br>return ResponseEntity.ok(response);<br>    }<br>}<br>单元测试代码<br><br>
  1. @ExtendWith(MockitoExtension.class)<br>class TaskMcpCallServerServicesTest {<br><br>    @Mock<br>    private ChatClient.Builder chatClientBuilder;<br><br>    @Mock<br>    private ChatClient chatClient;<br><br>    @InjectMocks<br>    private TaskMcpCallServerServices taskMcpCallServerServices;<br><br>    @Test<br>    void testGetAiResponse() {<br>        // Given<br>        String testPrompt = "test prompt";<br>        String expectedResponse = "test response";<br>        <br>        when(chatClientBuilder.build()).thenReturn(chatClient);<br><br>        // When<br>        ResponseEntity<String> actualResponse = taskMcpCallServerServices.getAiResponse(testPrompt);<br><br>        // Then<br>        assertEquals(expectedResponse, actualResponse.getBody());<br>    }
复制代码
  1. }<br>
复制代码
实践<br><br>Qwen3-Thinking模型<br><br>
1.png
<br>看上去解决问题思路没有问题,但实际还是不能解决ChatClient空指针问题。<br>基于Trae+Germin2.5 Flash模型对话如下:<br><br>
2.png
<br>我们查看修改后代码,并不理想<br>@RestController<br>@RequestMapping("/tools")<br>public class ToolController {<br>private final AiService aiService;<br>public ToolController(AiService aiService, ChatService chatService) {<br>this.aiService = aiService;<br>    }<br>    /**<br>     * 使用阿里云对话服务(AMAP)进行文本对话<br>     *<br>     * @param prompt 用户输入的对话内容<br>     * @return ResponseEntity 包含对话结果的HTTP响应<br>     */<br>    @GetMapping("")<br>public ResponseEntity amap(String prompt) {<br>return aiService.getAiResponse(prompt);<br>    }<br>}<br><br><br>Claude4<br><br>
3.png
<br>存在如下问题,大模型的知识还是跟不上组件更新<br>java: 找不到符号<br>   符号:   类 CallPromptSpec<br>   位置: 接口 org.springframework.ai.chat.client.ChatClient<br><br><br>TongYi Lingma-Qwen3-thinking再次尝试<br><br>
请对当前类引用类型ChatClient进行完全隔离,ChatClient来自Spring AI框架,我们期望隔离它,并且可以替换为其他AI类库的实现,请基于OOP编程原则修改相关关联代码。<br>
4.png
<br>单元测试没有修复,第二轮对话修复单元测试问题<br>
5.png
<br>最终Qwen3达到期望的结果<br>
  1. /**<br> * 聊天客户端适配器接口<br> * 提供统一的方法调用规范,可扩展支持不同AI框架的实现<br> */<br>public interface ChatAdapter {<br>    /**<br>     * 执行AI对话请求<br>     * @param prompt 用户输入内容<br>     * @return 返回处理结果<br>     */<br>    String chat(String prompt);<br>}
复制代码
  1. /**<br> * Spring AI框架适配器实现<br> */<br>@Component<br>public class SpringAiChatAdapter implements ChatAdapter {<br>    private final ChatClient chatClient;<br><br>    public SpringAiChatAdapter(ChatClient chatClient) {<br>        this.chatClient = chatClient;<br>    }<br><br>    @Override<br>    public String chat(String prompt) {<br>        return chatClient.prompt(prompt).call().content();<br>    }<br>}
复制代码
  1. @Service<br>public class TaskMcpCallServerServices implements AiService {<br>    private final ChatAdapter chatAdapter;<br><br>    /**<br>     * Constructs a new TaskMcpCallServerServices instance.<br>     * @param chatAdapter the ChatAdapter instance to use<br>     */<br>    public TaskMcpCallServerServices(ChatAdapter chatAdapter) {<br>        this.chatAdapter = chatAdapter;<br>    }<br><br>    @Override<br>    /**<br>     * Gets AI response for the given prompt by calling the MCP server.<br>     * @param prompt the input prompt to send to the AI<br>     * @return ResponseEntity containing the AI response<br>     */<br>    public ResponseEntity getAiResponse(String prompt) {<br>        String response = this.chatAdapter.chat(prompt);<br>        return ResponseEntity.ok(response);<br>    }<br>}
复制代码
  1. 单元测试代码
复制代码
  1. @ExtendWith(MockitoExtension.class)<br>class TaskMcpCallServerServicesTest {<br><br>    @Mock<br>    private ChatAdapter chatAdapter;<br><br>    @InjectMocks<br>    private TaskMcpCallServerServices taskMcpCallServerServices;<br><br>    @BeforeEach<br>    public void before()<br>    {<br>        MockitoAnnotations.openMocks(this);<br>        taskMcpCallServerServices = new TaskMcpCallServerServices(chatAdapter);<br>    }<br><br>    @Test<br>    void testGetAiResponse() {<br>        // Given<br>        String testPrompt = "test prompt";<br>        String expectedResponse = "test response";<br>        <br>        when(chatAdapter.chat(testPrompt)).thenReturn(expectedResponse);<br><br>        // When<br>        ResponseEntity actualResponse = taskMcpCallServerServices.getAiResponse(testPrompt);<br><br>        // Then<br>        assertEquals(expectedResponse, actualResponse.getBody());<br>    }
复制代码
  1. }
复制代码
  1. <br>
复制代码
Trae中Germin 2.5 Flash<br><br>
  1. <img width="761" height="4515" title="image"  alt="image" src="https://img2024.cnblogs.com/blog/15172/202506/15172-20250629215310234-1225760750.png" border="0">
复制代码
  1. 新生成文件,编译不通过,并且多次修复未果
复制代码
  1. <img width="901" height="459" title="image"  alt="image" src="https://img2024.cnblogs.com/blog/15172/202506/15172-20250629215311080-1443906469.png" border="0">
复制代码
Trae基于DeepSeek V3  0324实践<br><br>
  1. <img width="694" height="603" title="image"  alt="image" src="https://img2024.cnblogs.com/blog/15172/202506/15172-20250629215311935-345557468.png" border="0">
复制代码
  1. 存在单元测试问题,第二轮修复单元测试成功
复制代码
  1. <img width="1594" height="612" title="image"  alt="image" src="https://img2024.cnblogs.com/blog/15172/202506/15172-20250629215312967-735929455.png" border="0">
复制代码
  1. <br>
复制代码
/**<br> * Interface defining the contract for AI client implementations.<br> * Provides abstraction for different AI service providers.<br> */<br>public interface AiClient {<br>    /**<br>     * Gets AI-generated response for the given prompt.<br>     * @param prompt the input text to send to the AI service<br>     * @return the AI response content<br>     */<br>String getResponse(String prompt);<br>}<br>/**<br> * Service class for handling MCP server calls and AI responses.<br> * Implements AiService interface to provide AI response generation functionality.<br> */<br>@Service<br>public class TaskMcpCallServerServices implements AiService {<br>private final AiClient aiClient;<br>    /**<br>     * Constructs a new TaskMcpCallServerServices instance.<br>     * @param aiClient the AI client implementation<br>     */<br>public TaskMcpCallServerServices(AiClient aiClient) {<br>this.aiClient = aiClient;<br>    }<br>    @Override<br>    /**<br>     * Gets AI response for the given prompt by calling the MCP server.<br>     * @param prompt the input prompt to send to the AI<br>     * @return ResponseEntity containing the AI response<br>     */<br>public ResponseEntity getAiResponse(String prompt) {<br>String response = this.aiClient.getResponse(prompt);<br>return ResponseEntity.ok(response);<br>    }<br>}<br>直接让Claude4 重构<br><br>
  1. <img width="1477" height="930" title="image"  alt="image" src="https://img2024.cnblogs.com/blog/15172/202506/15172-20250629215314150-806432650.png" border="0">
复制代码
  1. <br>
复制代码
  1. <font size="3">重构基本是成功的,还使用简单工厂,但新生成UnitTest依赖的API存在版本问题,最终效果如下</font>
复制代码
  1. <img width="1253" height="666" title="image"  alt="image" src="https://img2024.cnblogs.com/blog/15172/202506/15172-20250629215315250-1662111963.png" border="0">
复制代码
总结<br><br>一、AI编程在OOP场景下的探索意义<br><br>1. 代码生成与模式识别的范式突破<br><br>
    <br>
  • 自动化模式实现:AI可通过分析海量开源代码库,自动生成符合设计模式的类结构(如工厂模式、单例模式),减少开发者对模式记忆的依赖。例如,GitHub Copilot已能根据注释生成完整的策略模式实现。<br>
  • 语义化代码补全:基于上下文的代码生成超越了传统IDE的语法补全,能理解“实现一个可序列化的订单对象”这类自然语言需求,直接生成符合OOP原则的类定义。<br>
2. 重构与演化的智能辅助<br><br>
    <br>
  • 架构漂移检测:AI可分析类之间的耦合度、继承层次深度等指标,量化代码异味(Code Smell),辅助决策是否需要引入依赖注入或抽象层。<br>
  • API演进预测:通过学习类库的历史更新日志,AI能预测未来版本可能弃用的方法,提前建议开发者使用适配器模式进行兼容性封装。<br>
3. 领域特定语言(DSL)的生成<br><br>
    <br>
  • OOP到DSL的映射:AI可将通用OOP结构转化为特定领域的DSL(如金融风控规则引擎),通过组合策略模式与状态模式,自动生成可配置的业务规则类。<br>
二、版本API知识更新滞后的挑战<br><br>1. 知识衰减的典型场景<br><br>
    <br>
  • 方法弃用链:例如,Java中java.util.Date到java.time包的迁移,涉及SimpleDateFormat到DateTimeFormatter的替换,但AI可能因训练数据滞后继续推荐旧API。<br>
  • 语义化变更:Python 3.10中collections.abc模块的调整,导致直接继承collections.MutableSequence的类需要修改导入路径。<br>
2. 上下文提示词的局限性<br><br>
    <br>
  • 局部最优陷阱:当开发者询问“如何实现一个线程安全的队列”,AI可能仅推荐queue.Queue而忽略项目已依赖的第三方库(如deque的线程安全封装)。<br>
  • 隐式依赖缺失:若类库A的v2版本移除了对类库B的兼容层,AI可能无法从代码上下文中推断出这种跨版本依赖关系。<br>
三、专家级综合判断的必要性<br><br>1. 领域知识的不可替代性<br><br>
    <br>
  • 业务逻辑映射:例如,在金融系统中,专家能判断某个API变更是否影响交易回滚逻辑,而AI可能仅关注语法正确性。<br>
  • 历史债务权衡:专家可评估重构成本与收益,决定是立即迁移到新API还是通过适配器模式暂时兼容。<br>
2. 认知推理链的构建<br><br>
    <br>
  • 因果推断:当AI建议使用新API时,专家会追问“该API在分布式环境下的线程安全性如何?”“是否有已知的性能回退案例?”<br>
  • 反事实分析:专家可模拟“如果采用备选方案B,未来升级到C版本时是否需要二次重构?”<br>
四、人机协同的进化路径<br><br>1. 增强型提示工程<br><br>
    <br>
  • 多模态输入:将API文档、提交历史、Issue跟踪系统数据融入上下文,例如提示词中包含“此方法在v2.1中标记为@Deprecated,但Issue #1234显示v3.0将恢复”。<br>
  • 动态知识注入:通过插件机制实时更新本地知识库,如将Maven仓库的最新版本元数据作为上下文补充。<br>
2. AI与专家的协作范式<br><br>
    <br>
  • 建议-验证循环:AI生成候选方案,专家通过批判性思维筛选(如“此方案是否违反里氏替换原则?”)。<br>
  • 可解释性增强:要求AI输出决策树(如“选择该API是因为其支持泛型,而旧版本仅处理Object类型”)。<br>
3. 持续学习的工程实践<br><br>
    <br>
  • 自动化测试用例生成:针对API变更,AI可生成覆盖边界条件的单元测试,专家只需验证测试用例的有效性。<br>
  • 金丝雀发布策略:在开发分支先部署AI建议的代码,通过监控日志和性能指标,由专家决定是否合并到主分支。<br>
五、未来展望:自适应OOP系统<br><br>最终,OOP与AI的融合将走向自适应软件系统<br>
    <br>
  • 动态类加载:根据运行时环境自动选择API版本(如开发环境用最新版,生产环境用稳定版)。<br>
  • 演化式设计:类结构不再静态定义,而是通过AI持续优化继承链和组合关系,类似生物体的自然选择过程。<br>
这一进程要求开发者从“代码编写者”转型为“系统架构师+AI训练师”,在OOP的抽象层次与AI的生成能力之间构建新的认知桥梁。<br>
  1. <br>
复制代码
<br>来源:程序园用户自行投稿发布,如果侵权,请联系站长删除<br>免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
6.png
7.png
8.png
9.png
10.png
11.png
您需要登录后才可以回帖 登录 | 立即注册