全部笔记
廉价的代码才是最贵的代码

2026年6月2日

廉价的代码才是最贵的代码

修改软件的成本不是一个常数——它是一条曲线,而这条曲线的形状由你的架构决定。跳过 SOLID、DRY、KISS 和 DI 并不能省钱,只是把账单挪到以后,还要加上利息。下面就用数字来讲讲这背后的经济账。

这部戏我不止看过一遍。一个团队决定快速交付、跳过架构——"先随便糊一下,这样更便宜,以后再清理。"第一个月,他们一路狂奔,功能天天上线,所有人都在互相道贺。到了第九个月,同一个团队要改一个按钮得花三周,每个估时都偏差三倍,没人敢碰支付代码,因为上次一碰就把结账流程搞挂了。那个"便宜"的版本,最后成了最贵的那个。

这不是一个关于"要把事情做对"的道德故事。这是经济学。而且这笔经济账,比大多数做软件的人意识到的要残酷得多。

修改成本是一条曲线,不是一个数字

有件事几乎没人算进去:**修改软件的成本不是恒定的。**在一个代码库里加某个功能很便宜,在另一个代码库里加同样的功能却贵得离谱。区别就在于架构。

这不是观点——这是被观测到的定律。20 世纪 70 年代,Meir Lehman 研究了大型系统在几十年间是如何演化的,他提出的软件演化定律之一就是"复杂度递增":随着系统演化,它的复杂度会上升,**除非你投入明确的工作去降低它。**你做的每一次改动都会增加一点点混乱。下一次改动得在这堆混乱里穿行,于是成本贵了一点。然后它又添上自己那份混乱。每次改动的成本就这样一路爬升。

这就是那条曲线:每个功能所需的工作量,以时间为横轴画出来。好的架构并不能让改动免费——它让曲线保持平坦。糟糕的架构则任由它指数式飙升。

两个团队,同一个产品

Martin Fowler 多年前就把这画成了设计耐力假说(Design Stamina Hypothesis)。想象两个团队在做同一个产品。把累计交付的功能数对时间画出来。跳过设计的那个团队一开始领先——他们没在架构上"浪费"时间。但两条线会交叉。Fowler 把这个交点叫做"设计回报线"。过了这条线,投资于设计的团队就一骑绝尘,再也不会把领先优势让回去。

陷阱在于,早期的领先是真实而显眼的——你能拿去演示。而那个交叉点在你远远越过它之前都是看不见的。等你感觉到曲线开始拐弯时,你早已经在一个撑不起第二层楼的地基上交付了你的"MVP"。你没有省下时间,你只是借了时间。

时间就是货币,而账单大得吓人

开发者花在跟代码库搏斗、而不是在里面构建的每一个小时,都是钱。而且这是一大堆小时。

  • Stripe 的开发者系数(Developer Coefficient)调查发现,开发者每周大约花42% 的时间在处理技术债和糟糕代码上——大致是 13.5 个小时用于维护,另外还有约 4 个小时专门用来跟烂代码角力。仅仅是烂代码这一项,他们估算每年造成的生产力损失就高达 850 亿美元
  • McKinsey 关于技术债的研究则把它摆上了资产负债表:CIO 们报告说,本该用于新产品的预算里有 10–20% 被悄悄挪去偿还技术债(其中三分之一的人说超过了 20%),而技术债的价值相当于他们整个技术资产价值的 20–40%。背负技术债最少的公司,营收增长速度比背负最多的公司快了大约 20%

把这些数字读成一句话:**廉价地构建并不会消除一笔成本,它只是把成本挪了地方。**你把它从构建预算里挪走——那是显眼的、一次性的、你本来想压缩的那一项——挪到了维护预算上,而维护预算是看不见的、永久的、还会复利滚动的。你把一次性买断换成了订阅,而且你没读续费条款。

那堵墙

曲线不只是变陡。它最终会变成垂直的。会有那么一个点,加一个功能要花太久,或者会弄坏太多东西,以至于你实际上加不动了——产品丧失了演化能力。与此同时,那个把曲线保持平坦的竞争对手,正悠然踱步从你身边走过,把你的客户向你索求的那些东西一个个加上去。

这件事最戏剧化的版本是 Knight Capital:多年积累、一直滞留在生产环境里的死代码,没有真正的部署纪律,然后在 2012 年的某个早晨,一次搞砸了的发布重新激活了本该被删掉的代码。在 45 分钟内,这家公司发出了数百万笔本不该发出的订单,损失了 4.4 亿美元——并就此不再作为一家独立公司存在。大多数团队从不会炸得这么惊天动地。他们做的是更安静、但总账更昂贵的事:他们渐渐磨到停摆。

接下来登场的,是一家公司能尝试的最贵的项目——大重写(Big Rewrite)。没人是因为旧代码丑才去重写的。他们重写,是因为曲线变成了垂直的,再没有别的招可出。重写不是病;它是你当初没买的那份架构的账单,一次性全部到账,而且来得正是最糟糕的时候。

"可是快速推进就意味着牺牲质量"——不是的

我听到最多的反驳是:架构是你为了又慢又稳而交的税,创业公司付不起。数据说的恰恰相反。长达十年的 DORA 研究(也就是 Accelerate 项目)反复得出同一个结论:部署最快的团队,故障率也最低。速度和稳定不是你需要去权衡的取舍——它们是同一个原因结出的两个果实:一个你能放心修改的代码库。好的架构正是用来买到这份"放心"的东西。"快还是好"这个选择本身是个伪命题;廉价的团队只是慢吞吞地两样都得不到。

这些原则到底在哪根杠杆上发力

这才是实践中真正要紧的部分。SOLID、DRY、KISS、DI 不是学院派的趣味。每一个都是作用在那条曲线形状上的一根杠杆:

  • 单一职责(SOLID 里的 S):一次改动只触及一处,而不是九处。每次编辑的爆炸半径都很小——这是"两小时"和"两周外加结账流程的一处回归 bug"之间的区别。
  • **DRY——每个事实只有一个真相来源:**当一条规则只存在于一个地方时,你改一次就行。当它被复制粘贴到八个地方时,你得改八次,然后漏掉第九个——而第九个,就是那个会上线的 bug。
  • **KISS:**能工作的最简单方案,就是理解成本最低的方案,而软件的大部分成本不在于写它,而在于它。你今天加进去的每一点小聪明,都是一笔税,由未来每一个读代码的人来交——包括半年后、早已不记得为什么这么写的你自己。
  • **DI——依赖注入:**当各部分依赖的是契约而不是具体实现时,你就能孤立地替换、测试和修改它们。(我把这个网站背后的 AI 提供方换掉,只改了一个配置值,而不是重写整个功能。这就是 DI 在为你买来一条平坦的曲线。)

这些都不是为了优雅。每一条都是为了不让"每次改动的工作量"往上爬。

为什么它这么难推销

"先随便糊一下"之所以总能赢下争论,靠的是一个会计把戏:**省下的钱是即时且可见的;付出的成本是延后且不可见的——而且它落在另一个人头上。**那个说"现在先便宜点"的创始人,这个季度就把胜利记进了账。而继承这套代码库的团队,要为此付上好几年的利息。正是这种不对称,让廉价方案赢下了会议——一直赢到它把公司输掉为止。

这也是为什么几乎没人会因为一篇文章就相信这件事。他们是在亲身经历过一次之后才信的——在大重写之后,在路线图原地踏步的那个季度之后,在资深工程师因为每次改动都变成一场恶斗而辞职之后。好的架构,是一堂你用昂贵方式学会、然后永远不会忘掉的课。它的价值,是随着伤疤组织一起到来的。

你可以预先为架构付费,用一种你掌控的货币:多一点设计时间,多一点纪律,几条始终如一地坚守的原则。或者你可以日后为它的缺席付费,用一种你不掌控的货币:流失的速度、爆掉的估时、一个再也动不了的产品,以及最终一场可能赶不及完成的重写。账单无论如何都会来。你唯一能选的,只是利率。

"便宜",从来就不是那个便宜的选项。

评论

暂无评论

登录以参与讨论。

做第一个分享想法的人。