第二章:技术债务——为了赶进度写烂代码,后期维护成本爆炸

技术债务这个词,我猜你肯定听过。但说实话,很多人把它当成一个抽象概念,觉得「欠债嘛,以后还就行了」。

我在项目里见过太多这样的场景:产品经理拍着桌子说「这周五必须上线」,开发组长咬着牙说「先这么写,后面再重构」。结果呢?那个「后面」永远没来。等真正需要改的时候,你会发现——改一行代码,崩三个模块。嗯,这就是技术债务的利息。

2.1 技术债务到底长什么样?

说白了,技术债务就是你现在图省事,给未来埋的雷。我把它分成三类,你看看自己踩过几个:

  • 代码债务:变量名用 a、b、c,函数写 500 行,复制粘贴大法好
  • 架构债务:没有分层、模块耦合严重、一个类干十件事
  • 测试债务:单元测试覆盖率 0%,上线全靠「我觉得没问题」

核心观点:技术债务不是 bug,但它比 bug 更可怕。bug 你修了就完了,债务是每天利滚利,直到你连本金都还不起。

2.2 为什么我们总在欠债?

你想想看,哪个程序员一开始就想写烂代码?还不是被逼的。我总结了几种典型场景:

  1. Deadline 是第一生产力——产品说「先上线,后面优化」,然后就没有然后了
  2. 技术选型拍脑袋——「这个框架最新最火,就用它!」结果发现社区文档都没写完
  3. 重构?不存在的——「代码能跑就别动它」,这是最危险的想法
  4. 团队缺乏代码评审——每个人按自己的风格写,最后代码像拼图一样混乱

我记得有个项目,团队为了赶一个双十一活动,用了一个刚出 beta 版的数据库中间件。当时觉得「反正量不大,出问题再修」。结果活动当天,中间件内存泄漏,整个服务挂了 40 分钟。那个月的绩效,你懂的。

2.3 技术债务的利息怎么算?

我习惯用一个简单的公式来估算债务成本:

维护成本 = 原始开发时间 × (1 + 债务系数)^月数

债务系数取决于你的代码质量:

代码质量等级 债务系数 6个月后成本倍数
良好(有测试、有文档) 0.1 1.77 倍
一般(能跑、没测试) 0.3 4.83 倍
糟糕(复制粘贴、无结构) 0.5 11.39 倍

你看,半年后糟糕代码的维护成本是原始开发的 11 倍。这就是为什么很多项目做到后面,改一个按钮要花三天。

2.4 怎么还债?我的实战经验

我在项目中遇到过最严重的债务问题,是一个用了三年的老系统。代码里到处都是「TODO: 后面再改」,但从来没人改。后来我们用了三步走策略:

第一步:识别债务

先别急着动手改。我建议用静态代码分析工具扫一遍,找出:

  • 圈复杂度超过 15 的函数
  • 超过 200 行的文件
  • 重复代码块
  • 没有单元测试的模块

第二步:分类优先级

不是所有债务都要马上还。我习惯分三个等级:

优先级 特征 处理方式
P0(立即还) 影响线上稳定性、阻塞新功能开发 立刻重构,暂停新功能
P1(本周还) 代码难以理解、修改风险高 安排专门的重构时间
P2(慢慢还) 风格问题、轻微冗余 日常开发中顺手改进

第三步:小步重构

千万别想着「一次性重写整个系统」。我吃过这个亏——重写了三个月,上线第一天就崩了。正确的做法是:

// 重构前:一个函数干所有事
public void processOrder(Order order) {
    // 200 行代码,包含验证、计算、存储、通知
}

// 重构后:拆分成小函数
public void processOrder(Order order) {
    validate(order);
    calculate(order);
    save(order);
    notify(order);
}

private void validate(Order order) { /* 20 行 */ }
private void calculate(Order order) { /* 30 行 */ }
private void save(Order order) { /* 40 行 */ }
private void notify(Order order) { /* 15 行 */ }

我的小技巧:每次改代码时,遵循「童子军规则」——让营地比你发现时更干净。改一个函数,就顺手优化一下它的可读性。积少成多,债务就慢慢还清了。

2.5 如何从源头避免技术债务?

说实话,完全避免是不可能的。但我们可以控制债务的规模。我总结了四条铁律:

  1. 技术选型要做 POC——别听别人说好就上,自己写个 demo 跑一遍
  2. 代码评审必须执行——哪怕再急,也要有人看一眼代码
  3. 单元测试不能省——至少核心逻辑要有测试,这是你的安
  4. 定期安排重构时间——比如每个迭代留 20% 的时间还技术债

避坑指南:我曾经在一个项目里,为了赶进度允许团队「先写烂代码,后面再改」。结果三个月后,那个模块的 bug 率是其他模块的 5 倍,每次改 bug 都会引入新 bug。最后不得不花两周时间重写。嗯,从那以后我再也不信「后面再改」这种话了。

2.6 技术债务的真相

最后说点实在的。技术债务不是技术问题,是管理问题。它反映的是:

  • 产品经理不懂技术成本
  • 技术负责人不敢说「不」
  • 团队缺乏长期思维

如果你现在正被技术债务折磨,我的建议是:先停下来,算算利息。很多时候你会发现,花一周重构,比花一个月修 bug 划算得多。

记住一句话:烂代码不会自己变好,它只会越来越烂。要么现在还债,要么以后加倍还。你自己选。