我用 AI 重构了 3 万行遗留代码,踩过的坑都在这了(附完整方案)
说实话,接手那个老项目的时候,我是真没想到代码能烂到这种程度。
背景:一个让人头疼的遗留系统
去年年底,公司让我负责重构一个跑了 5 年的订单系统。打开代码库的那一刻,我整个人都不好了:
- 单个文件超过 8000 行
- 一个函数嵌套了 7 层 if-else
- 全局变量满天飞
- 没有任何单元测试
// 原始代码 - 典型的"面条代码"
public void processOrder(Order order) {
if (order != null) {
if (order.getStatus() != null) {
if (order.getStatus().equals("PENDING")) {
if (order.getItems() != null && order.getItems().size() > 0) {
// 200 行处理逻辑...
}
}
}
}
}这种代码,改一个地方能崩三个模块。老板说"能不能用 AI 帮忙重构",我心想:死马当活马医吧。
第一步:让 AI 理解代码结构
我用的工具是 Cursor + Claude,先把整个模块喂给 AI,让它帮我梳理调用关系。
# 用 AI 生成代码依赖分析脚本
import ast
import os
def analyze_dependencies(file_path):
"""分析 Python 文件的依赖关系"""
with open(file_path, 'r') as f:
tree = ast.parse(f.read())
imports = []
for node in ast.walk(tree):
if isinstance(node, ast.Import):
for alias in node.names:
imports.append(alias.name)
elif isinstance(node, ast.ImportFrom):
imports.append(f"{node.module}.{node.names[0].name}")
return imports
# 扫描整个项目
for root, dirs, files in os.walk('./src'):
for file in files:
if file.endswith('.py'):
path = os.path.join(root, file)
deps = analyze_dependencies(path)
print(f"{path}: {deps}")AI 帮我画出了一张完整的依赖图,哪些模块耦合最严重一目了然。
第二步:分模块重构
重构的核心原则:小步快跑,每次只改一个点。
2.1 提取函数,消除嵌套
让 AI 把那个 7 层嵌套的函数拆成多个小函数:
// 重构后 - 清晰多了
public void processOrder(Order order) {
if (!isValidOrder(order)) {
throw new InvalidOrderException("订单无效");
}
if (order.getStatus() != OrderStatus.PENDING) {
return; // 非待处理订单直接返回
}
processOrderItems(order.getItems());
updateOrderStatus(order);
sendNotification(order);
}
private boolean isValidOrder(Order order) {
return order != null
&& order.getStatus() != null
&& order.getItems() != null
&& !order.getItems().isEmpty();
}2.2 引入设计模式
AI 建议我用策略模式替换那堆 if-else:
// 策略接口
public interface OrderProcessor {
boolean canProcess(Order order);
void process(Order order);
}
// 普通订单处理器
public class NormalOrderProcessor implements OrderProcessor {
@Override
public boolean canProcess(Order order) {
return order.getType() == OrderType.NORMAL;
}
@Override
public void process(Order order) {
// 普通订单处理逻辑
}
}
// 处理器工厂
public class OrderProcessorFactory {
private List<OrderProcessor> processors;
public OrderProcessor getProcessor(Order order) {
return processors.stream()
.filter(p -> p.canProcess(order))
.findFirst()
.orElseThrow(() -> new UnsupportedOrderException(order.getType()));
}
}第三步:自动化测试
重构最怕的就是改出新 bug。我让 AI 帮我生成单元测试:
import pytest
from order_service import OrderService, InvalidOrderException
class TestOrderService:
def setup_method(self):
self.service = OrderService()
def test_process_valid_order(self):
"""测试正常订单处理"""
order = {"id": "001", "status": "PENDING", "items": [{"sku": "A", "qty": 1}]}
result = self.service.process(order)
assert result["status"] == "PROCESSED"
def test_process_null_order(self):
"""测试空订单抛异常"""
with pytest.raises(InvalidOrderException):
self.service.process(None)
def test_process_empty_items(self):
"""测试空商品列表"""
order = {"id": "002", "status": "PENDING", "items": []}
with pytest.raises(InvalidOrderException):
self.service.process(order)踩过的坑
坑 1:AI 生成的代码不能直接用
AI 有时候会"幻觉",生成看起来对但实际有 bug 的代码。比如它给我写了一个并发处理逻辑,结果没考虑线程安全,上线后数据直接乱了。
教训:AI 生成的代码必须人工 review,尤其是涉及并发、事务的地方。
坑 2:上下文窗口限制
3 万行代码不可能一次性喂给 AI。我试过把整个模块丢进去,结果 AI 直接"失忆",前面的分析后面就忘了。
解决方案:按功能模块拆分,每次只处理一个子模块。
坑 3:重构后的性能问题
AI 建议我把一个循环查询改成 Stream 操作,代码是优雅了,但性能下降了 30%。
// AI 建议的写法 - 优雅但慢
List<Order> result = orders.stream()
.filter(o -> o.getStatus() == PENDING)
.map(this::enrichOrder)
.collect(Collectors.toList());
// 最终方案 - 批量处理
List<Order> pendingOrders = orders.stream()
.filter(o -> o.getStatus() == PENDING)
.collect(Collectors.toList());
enrichOrdersBatch(pendingOrders); // 批量enrichment最终成果
经过 2 个月的重构:
| 指标 | 重构前 | 重构后 |
|------|--------|--------|
| 代码行数 | 32,000 | 18,000 |
| 圈复杂度 | 平均 25 | 平均 8 |
| 测试覆盖率 | 12% | 78% |
| 线上故障 | 月均 5 次 | 月均 0.5 次 |
总结
AI 辅助重构遗留代码是可行的,但要记住几点:
1. AI 是助手,不是替代品 - 关键决策还是要人来
2. 小步迭代 - 不要想一口吃成胖子
3. 测试先行 - 没有测试的重构就是裸奔
4. 持续 review - AI 生成的代码一定要人工检查
如果你也在头疼遗留代码,不妨试试这个思路。有问题欢迎评论区交流。
读者评论 2