《从 300 行到 30 万行代码,我学到的 5 个重构教训》

一、背景
三年前,我加入了一家创业公司,接手了一个「看起来还不错」的项目。
代码量:300 行。
功能:能用。
架构:没有。
反正能跑就行 —— 前同事的原话。
三年后,这个项目变成了 30 万行,团队从 1 个人变成了 10 个人。当系统开始在线上频繁出问题时,我们终于意识到:代码量和维护成本是呈指数级上升的。
这篇文章记录的是我用真金白银(线上故障)换来的 5 个教训。
二、教训一:提前抽象,但不要过度抽象
最早的 300 行代码里,有个 Utils.java,里面放了 3 个方法。
后来变成 StringUtils、DateUtils、FileUtils、HttpUtils、JsonUtils……
问题是:过度抽象导致一个新同事要改一个 bug,需要跨 5 个工具类才能搞清楚调用链路。
现在的做法:
用 @UtilityClass(Lombok)标记工具类
每个工具类不超过 200 行
如果某个方法只有一个调用方,先内联,等出现第三个调用方再提取
三、教训二:命名不是小事
这是最容易被忽视的问题。

// ❌ 错误示范
List dataList = getData();
Map<String, Object> m = new HashMap<>();
process(m);

// ✅ 正确示范
List pendingOrders = fetchPendingOrders();
Map<String, Object> orderParams = new HashMap<>();
processPayment(orderParams);

为什么重要? 因为代码读的次数远远多于写的次数。好的命名让代码自解释,不需要注释。
四、教训三:数据库设计 —— 不要「存就完了」
300 行的时候,数据存在一个超大 JSON 字段里。读出来,改一下,写回去。
30 万行的时候,这个 JSON 字段 50KB,每次更新都要全量读写。
踩过的坑:
JSON 字段没有索引,查询全表扫描
多个字段混在一个 JSON 里,改一个也要写整个
数据一致性全靠业务代码保障
现在的做法:
能用关系表就别用 JSON
必须用 JSON 时,确保它有索引(MySQL 8.0 支持 JSON 索引)
大字段和核心字段分表存储
五、教训四:单元测试不是负担,是保险
我以前觉得写单元测试浪费时间,直到有一次改了一个「看起来没影响」的代码,结果把三个月的核心逻辑全改崩了。
从那以后我坚持三个原则:
核心链路必须覆盖:支付、登录、下单
一次性写对更重要:TDD 太理想化,但至少补测试
测试失败及时修:CI 挂了就停下手头的事修
三个月后,我们的回归测试从 2 小时缩短到 15 分钟,线上故障减少了 80%。

六、教训五:重构不是重写
300 行到 30 万行之间,我们经历过一次大重构——彻底重写。
结果是:花了 6 个月,推迟了三个版本上线,上线后还有一堆 bug。
重写的问题:
丢失了对业务细节的理解
测试数据要迁移
新系统总有意想不到的边界情况
渐进式重构才是正道:
用防腐层隔离新旧代码
每次只重构一个模块
用特性开关逐步切换流量
七、写在最后
代码行数从 300 涨到 30 万,真正重要的不是代码量,而是代码的演化能力。
好的架构不是设计出来的,是不断重构出来的。
你怎么看待「代码重构」这件事?遇到过哪些坑?欢迎在评论区聊聊 👇