跳到正文

技术债务管理:何时偿还、何时容忍

桃总
发布日期:
1 min read
编辑此文

“技术债务”这个比喻最早是 Ward Cunningham 在 1992 年提出的。他的原意是:为了快速交付,你可以暂时走捷径,但要像欠债一样记住它,并在未来偿还。就像金融债务一样,适度的杠杆可以加速发展,但失控的债务会压垮你。

问题在于,大多数团队既不记录技术债,也没有偿还的计划。技术债就这样无声地堆积,直到有一天你发现:改一个按钮的颜色需要三天。

技术债的四象限

Martin Fowler 提出过一个技术债的四象限分类,我觉得非常实用:

审慎的(Deliberate)鲁莽的(Reckless)
有意识的”我们知道这不是最优方案,但为了赶 deadline 先这样做,之后再重构""我们没时间做设计,先写能跑的代码”
无意识的”做完之后才发现有更好的方案""什么是设计模式?”

左上角(审慎 + 有意识)是健康的技术债:你清楚地知道自己在做什么权衡,有计划在未来偿还。

右上角(鲁莽 + 有意识)是危险的技术债:你知道代码质量差,但选择了不管不顾。

左下角(审慎 + 无意识)是不可避免的技术债:随着你对问题域理解的深入,早期的设计自然会变得不够好。

右下角(鲁莽 + 无意识)是最可怕的技术债:团队能力不足,写出来的代码本身就有问题,而且没有人意识到。

什么时候必须还债

不是所有技术债都需要立即偿还。但以下几种情况,拖得越久代价越高:

1. 影响交付速度的债

如果一个模块已经脆弱到”每次改它都要修三个 Bug”,那你在这个模块上的每一次迭代都在为之前的技术债支付利息。当利息超过了偿还成本,就该重构了。

一个简单的判断方法:如果一个功能的开发时间中,超过 50% 花在”理解和绕过遗留代码”上,那这笔债该还了。

2. 安全相关的债

跳过了认证、用了明文存密码、没做输入验证——这类债务没有”慢慢还”的选项。安全相关的技术债是定时炸弹,一旦被利用,损失不是代码层面的,而是业务层面甚至法律层面的。

3. 影响团队招聘和留存的债

如果你的代码库糟糕到新人入职三个月都无法独立提交代码,或者资深工程师因为”代码太烂”而离职,那技术债已经在影响你最重要的资产——人。

什么时候可以欠着

1. 即将废弃的模块

如果一个功能计划在三个月内下线,花两周去重构它就是浪费。用注释标记清楚”此模块将在 X 版本废弃”,把时间花在更有价值的地方。

2. 探索期的代码

产品方向还不确定的时候,写”完美”的代码是一种浪费。因为你大概率会在方向明确后重写它。探索期的代码要做到”能跑、能读、能删”——而不是”能扩展、能复用、能维护十年”。

3. 边缘场景的处理

如果一个 edge case 每年只出现一次,而修复它需要重构核心模块,那用 try-catch 包住然后记个日志就够了。完美主义在边缘场景上的 ROI 极低。

如何管理技术债

可见性是第一步

大多数技术债之所以失控,是因为它是”隐性”的。只有写代码的人知道,管理层看不到,产品经理不关心。

把技术债显性化:

20% 规则

Google 曾经有”20% 时间做个人项目”的传统。类似的,一些团队会保留每个 sprint 20% 的时间来偿还技术债。

这个比例不一定精确,但核心思想是对的:技术债偿还不应该是”等有空再做”的事情,而应该是开发流程的常规组成部分。

重构的粒度

不要做”大重构”。大重构意味着长期分支、大量冲突、无法增量交付、风险不可控。

更好的做法是”持续小重构”:

Martin Fowler 说过:“重构应该像刷牙一样——每天做一点,而不是等牙疼了再去看牙医。“

度量技术债

几个有用的度量指标:

最后

技术债不是敌人,失控的技术债才是。

最好的工程团队不是”零技术债”的团队——那种团队通常交付太慢。最好的团队是能够有意识地承担技术债、清楚地记录技术债、有节奏地偿还技术债的团队。

借用金融的话说:关键不是不借债,而是借得明白、还得起、利息可控。

上一篇
事件驱动架构的可靠性:消息发出去,不等于事情完成了
下一篇
读书笔记:《思考,快与慢》给工程师的提醒