加载中...
返回AI 编程实战
AI 编程知识库 · AI 编程实战 · 企业团队落地

老项目增量开发策略

概念图

版本说明:本文基于 Michael Feathers《Working Effectively with Legacy Code》的核心理念,结合 AI 辅助开发的实践撰写。

适用技术版本:Java 17+、Spring Boot 3.x、JUnit 5、Claude Code v1.x、Maven 3.9+。

内容时效:本文内容基于 2026 年 4 月验证。AI 工具能力可能随版本迭代变化,文中提到的具体 AI 能力(如代码理解、Seam 识别、特征测试生成等)以实际使用时的模型版本为准。建议读者关注 Claude Code 更新日志以获取最新能力信息。

适用对象:技术负责人、高级开发者、维护老项目的团队。

前置知识:第12篇项目接入AI、第16篇代码考古、第20篇测试编写。

一、老项目增量开发的核心挑战

第12篇讲的是"让 AI 认识项目"——配置 CLAUDE.md / AGENTS.md,让 AI 理解项目结构。本篇讲的是"在老项目上安全开发"——拿到一个新需求,如何在已有代码上安全地完成修改。

Michael Feathers 在《Working Effectively with Legacy Code》中给出了一个经典定义:遗留代码就是没有测试的代码 。这个定义直指核心问题——没有测试保护的代码,每次修改都像在雷区行走。

老项目增量开发的三个核心挑战:

挑战 说明 后果
不理解现有设计 老代码缺乏文档,设计决策散落在 Git 历史中 修改破坏了隐式约定
隐式依赖多 老项目的模块间耦合严重,牵一发动全身 小改动引发连锁故障
缺少测试保护 老项目通常测试覆盖率低 改了不知道有没有改坏

Martin Fowler 指出,GenAI 在遗留代码现代化中的核心价值不是"生成新代码",而是"理解现有代码"——帮助开发者快速建立对大型、复杂、长期迭代的遗留系统的认知 。

二、安全开发的四个策略

策略 1:精准定位修改区域

在老项目中,最大的风险不是"不知道怎么改",而是"改错了地方"或"改了不该改的代码"。

定位修改区域的方法:

步骤 1:从需求出发,找到业务入口
  - 用户触发的 API 接口
  - 定时任务的调度入口
  - 消息队列的消费入口

步骤 2:从入口追踪调用链
  - Controller → Service → DAO → DB
  - 标注调用链上涉及的所有文件和类

步骤 3:圈定最小修改范围
  - 只修改直接相关的文件
  - 不动间接依赖的代码
  - 记录"为什么不动这些代码"

Anthony Bordonaro 提出了"代码考古"的系统化技术——使用 AI 从入口点向内构建分层心智模型,逐步建立对代码库架构、约定、数据流和隐式决策的理解 。

策略 2:确保不破坏现有功能

在不破坏现有功能的前提下做修改,这是老项目开发的铁律。

Michael Feathers 提出了"特征测试"(Characterization Test)的概念 :在不理解代码逻辑的情况下,先写测试记录代码的当前行为,然后才能安全修改。

特征测试 vs 单元测试:

特征测试:记录代码"现在做什么"(可能是 bug,也可能不是)
单元测试:验证代码"应该做什么"(基于需求定义)

在老项目中,先写特征测试锁定当前行为,
然后再写单元测试验证新逻辑。

特征测试完整操作示例:

以一个老项目的 CouponValidator.validate() 方法为例,展示从发现老方法到写出特征测试的全流程:

# 第1步:定位需要修改的老方法
# 假设老项目没有测试,先通过 AI 分析代码结构
claude -p "分析 src/main/java/com/example/coupon/CouponValidator.java 中的 validate() 方法,列出所有输入参数和可能的返回值"

# AI 输出:
# validate() 方法接收 Coupon 对象,返回 ValidationResult
# 输入组合:有效券/已过期/已使用/金额不满足/券不存在 → 5种场景
# 当前没有单元测试覆盖
AI 编程知识库会员专享内容
开通后解锁「老项目增量开发策略」全文,AI 编程知识库全年访问

扫码添加企业微信,找大熊掌门开通会员

企业微信二维码

添加后说明想开通的会员类型即可

加载中...