2022年是AI大爆发的一年。

DALL-E 2让AI绘画火遍全球,Midjourney、Stable Diffusion层出不穷。这也让我开始思考:AI既然能画画,能不能帮我写代码、重构代码?

本文分享我在AI大模型时代,用AI辅助工具(包括GitHub Copilot等)进行代码重构的经历,从烂代码到优雅代码,包括重构的原则、步骤、工具、案例,以及AI在代码重构中的作用和局限。

一、背景

1. 为什么要重构

我们项目里有一段祖传代码,是几年前一个实习生写的。

这段代码的问题:

  • 一个函数500多行,没人能看懂
  • 变量名是a、b、c,不知道什么意思
  • 复制粘贴了很多次,到处都是重复代码
  • 没有注释,没有文档
  • 经常出bug,改一个地方崩三个地方
  • 性能很差,一个简单查询要几秒

每次要改这段代码,大家都头疼。但因为它在核心链路上,没人敢动,怕改崩了。

2. 为什么现在重构

最近,这段代码又出bug了,而且性能问题越来越严重。

领导说:"必须重构了,再这样下去不行。"

于是,这个任务落到了我头上。

3. AI能帮什么忙

2022年,AI编程工具已经比较成熟了:

  • GitHub Copilot:AI代码补全
  • 各种AI代码审查工具
  • AI代码解释工具

我想:既然DALL-E 2能根据文字生成图片,那AI能不能帮我理解烂代码、生成优雅代码?

于是,我开始尝试用AI辅助重构。

二、重构前的准备

1. 理解代码

重构的第一步,是理解代码。

这段代码是一个订单处理函数,逻辑是:

  • 接收订单信息
  • 验证订单
  • 计算价格
  • 扣减库存
  • 创建订单
  • 发送通知

但因为写得太烂,逻辑散落在各处,还有很多莫名其妙的判断。

我花了两天时间,才大概搞懂这段代码在做什么。

2. AI辅助理解

我用AI工具辅助理解代码:

  • 把代码贴给AI,让它解释这段代码在做什么
  • 让AI画出代码的流程图
  • 让AI找出代码中的问题

AI的解释,帮我快速理解了代码的大致逻辑。虽然有些地方AI理解错了,但整体方向是对的。

3. 写测试

重构前,一定要有测试。

我先给这段代码写了单元测试,覆盖主要的业务场景。这样,重构的时候,只要测试通过,就说明功能没改坏。

写测试的过程中,我也更深入地理解了代码的逻辑。

三、重构的原则

重构不是重写,是在不改变功能的前提下,改善代码结构。

我遵循的重构原则:

1. 小步快跑

不要一次性重构完,要一小步一小步来。

  • 每一步只做一个小改动
  • 每改一步,跑一遍测试
  • 确保每一步都是正确的
  • 出了问题,容易回滚

2. 不改变功能

重构的过程中,不能改变功能。

  • 输入相同,输出必须相同
  • 边界条件要保持一致
  • 异常处理要保持一致
  • 性能不能下降太多

3. 先改结构,再优化性能

先把代码结构改好,再优化性能。

  • 结构清晰了,性能问题才容易定位
  • 不要在烂代码上做性能优化
  • 结构改好后,很多性能问题自然就解决了

4. AI辅助,人来决策

AI是辅助工具,最终决策要靠人。

  • AI可以给建议,但人要判断对不对
  • AI生成的代码,人要审查
  • 不要盲目相信AI,AI也会出错

四、重构的步骤

第一步:提取函数

500行的函数,首先要拆分成小函数。

我用AI辅助,把大函数拆成小函数:

  • 验证订单的逻辑,提取成validateOrder
  • 计算价格的逻辑,提取成calculatePrice
  • 扣减库存的逻辑,提取成deductStock
  • 创建订单的逻辑,提取成createOrder
  • 发送通知的逻辑,提取成sendNotification

AI帮我识别了哪些代码可以提取成函数,还帮我生成了函数签名。但具体怎么拆,还是我自己决定的。

拆完之后,主函数变成了这样:

function processOrder(order) {
  validateOrder(order);
  const price = calculatePrice(order);
  deductStock(order);
  const orderId = createOrder(order, price);
  sendNotification(orderId);
  return orderId;
}

清晰多了。

第二步:重命名变量和函数

原来的变量名是a、b、c、temp1、temp2,根本看不懂。

我用AI辅助,给变量和函数起有意义的名字:

  • a → orderId
  • b → totalPrice
  • c → stockQuantity
  • temp1 → validatedOrder
  • temp2 → priceDetail

AI根据上下文,给出了一些命名建议。我筛选了一下,选了最清晰的名字。

改完名字,代码的可读性大大提升。

第三步:消除重复代码

原来的代码里,有很多复制粘贴的重复代码。

我用AI辅助,找出重复的代码,提取成公共函数:

  • 价格计算的逻辑,在好几个地方重复了,提取成calculatePrice
  • 日期格式化的逻辑,重复了好几次,提取成formatDate
  • 错误处理的逻辑,到处都是,提取成handleError

AI帮我找出了很多重复代码,有些是我没注意到的。

第四步:优化数据结构

原来的代码里,数据结构很乱。

比如,订单信息用一个大对象传,里面什么字段都有,还有很多嵌套。

我重新设计了数据结构:

  • Order:订单基本信息
  • OrderItem:订单项
  • PriceDetail:价格明细
  • StockInfo:库存信息

AI帮我分析了数据的使用方式,给出了数据结构的建议。我根据业务逻辑,做了调整。

第五步:添加注释和文档

重构完,要加注释和文档。

  • 每个函数,加JSDoc注释
  • 复杂的逻辑,加行内注释
  • 模块的入口,加模块说明
  • 写一个README,说明模块的功能和用法

AI可以帮我生成注释的草稿,但我会根据实际情况修改,确保注释准确。

第六步:优化性能

结构改好之后,开始优化性能。

我用性能分析工具,找出性能瓶颈:

  • 数据库查询太多,加了缓存
  • 循环里做了重复计算,提到循环外面
  • 有些查询可以批量,改成批量查询
  • 加了索引,查询变快了

AI帮我分析了性能瓶颈,给出了一些优化建议。但具体怎么优化,还是要靠经验和测试。

五、AI在重构中的作用

经过这次重构,我总结了AI在代码重构中的作用。

1. 帮助理解代码

AI可以帮你理解烂代码:

  • 解释代码在做什么
  • 生成代码的流程图
  • 找出代码中的问题
  • 识别代码的模式

对于看不懂的祖传代码,AI是一个很好的助手。

2. 生成重构建议

AI可以给你重构建议:

  • 哪些函数可以拆分
  • 哪些代码重复了
  • 哪些变量名不好
  • 哪些地方可以优化

AI的建议,很多是有价值的,可以作为参考。

3. 生成代码模板

AI可以帮你生成代码模板:

  • 函数签名
  • 类的结构
  • 测试用例
  • 注释模板

这些模板,可以节省很多时间。

4. 代码审查

AI可以帮你做代码审查:

  • 找出潜在的bug
  • 找出安全隐患
  • 找出性能问题
  • 给出改进建议

AI代码审查,可以作为人工审查的补充。

六、AI的局限

AI虽然有用,但也有局限。

1. 理解不深

AI对代码的理解,是表面的,不深入。

  • 它能看出代码的模式,但不理解业务逻辑
  • 它能给出重构建议,但不知道哪些改动会影响业务
  • 它能生成代码,但不知道代码是否符合系统架构

所以,AI的建议,需要人来判断和筛选。

2. 会出错

AI会出错,有时候错得很离谱。

  • 生成的代码有bug
  • 解释代码的时候理解错了
  • 重构建议不符合实际情况
  • 有时候会"一本正经地胡说八道"

所以,AI生成的代码,一定要审查,不能直接用。

3. 不了解上下文

AI不了解项目的上下文:

  • 不知道系统的架构
  • 不知道团队的编码规范
  • 不知道业务的特殊需求
  • 不知道历史遗留问题

所以,AI的建议,有时候会脱离实际。

4. 不能替代思考

AI不能替代人的思考。

  • 重构的方向,要人来定
  • 重构的方案,要人来设计
  • 重构的风险,要人来评估
  • 重构的质量,要人来保证

AI是工具,人是主体。

七、重构后的效果

重构之后,效果很明显。

1. 代码质量

  • 代码行数:从500多行降到200多行
  • 函数数量:从1个变成10多个小函数
  • 变量名:全部有意义
  • 注释:齐全
  • 重复代码:基本消除

2. 可维护性

  • 新人看代码,半天就能理解
  • 改需求,只需要改对应的小函数
  • 出bug,容易定位
  • 加功能,不容易影响其他地方

3. 性能

  • 查询速度:从3秒降到300毫秒
  • 内存使用:减少了40%
  • 并发能力:提升了3倍

4. 团队反馈

团队成员都说:

  • "这段代码终于能看懂了"
  • "改需求不用头疼了"
  • "出bug也好定位了"
  • "早该重构了"

八、经验总结

1. 重构要趁早

烂代码越拖越难改。

  • 越早重构,成本越低
  • 拖得越久,依赖越多,越难改
  • 不要等代码烂到不能再烂了才重构

2. 测试是保障

重构前一定要有测试。

  • 没有测试的重构,就是赌博
  • 测试覆盖越全,重构越放心
  • 重构过程中,也要不断补充测试

3. 小步快跑

不要一次性重构完。

  • 一小步一小步来
  • 每一步都要测试
  • 每一步都要可回滚
  • 不要贪多求快

4. AI是好帮手

AI是重构的好帮手,但不是万能的。

  • 用AI辅助理解代码
  • 用AI生成重构建议
  • 用AI生成代码模板
  • 但最终决策要靠人

5. 不要追求完美

重构不要追求完美。

  • 先改最烂的部分
  • 先解决最紧急的问题
  • 剩下的可以慢慢改
  • 完美是好的敌人

九、写在最后

这次代码重构,从烂代码到优雅代码,花了我一周时间。

AI工具帮了我不少忙,尤其是在理解代码、生成建议、生成模板方面。但AI也有局限,最终的决策和质量保证,还是要靠人。

2022年了,AI发展很快。DALL-E 2能画画,Copilot能写代码,未来AI会越来越强大。但AI终究是工具,它能帮我们提高效率,但不能替代我们的思考和判断。

代码重构,本质上是人的工作。理解业务、设计方案、控制风险、保证质量,这些都需要人来做。AI可以辅助,但不能替代。

最后,用一句话总结:"AI是重构的好帮手,但不是万能的。用AI辅助,靠人决策,小步快跑,测试保障,才能把烂代码改成优雅代码。"

愿你的代码,越来越优雅。