为什么你不敢重构那段祖传代码:亏损心理学
为什么你不敢重构那段祖传代码:亏损心理学
Fen9Pi,把复杂东西拆明白。本文 6 分钟,带你拆一个所有工程师都遇过、但没人说清过的问题。
每个老项目里都有那么一段代码:没人记得它为什么这么写,注释只有一句「别动,会炸」,git blame 查到底是一个 2014 年就离职的人。测试不敢删,重构没人接,「优化它」在 TODO 里躺了五年。
大家管这叫祖传代码。但你有没有想过一个更扎心的问题——为什么明知道它是屎山,你也不敢动它?
「技术风险高」是标准答案,但它解释不了另一件事:同样这些人,删起自己上个月写的代码毫不手软,甚至一边删一边爽。区别不在代码,在心理。
这个问题的最精准答案,我是在一本讲交易员的书里找到的——《止损:如何克服贪婪和恐惧》,作者吉姆·保罗,芝加哥交易所史上最年轻的董事之一,然后用 12 个月把自己赔到破产,后来把「人为什么不肯认赔」这件事拆到了骨头缝里。这书是哥伦比亚商学院的经典教材,姚金刚的推荐书单里也有它。
炒股不肯割肉,和工程师不敢碰祖传代码,是同一种病。今天拆给你看。
病根:把「这一笔亏了」翻译成「我错了」
吉姆·保罗的核心发现就一句话:亏损本来是外部的、客观的业务成本,一旦你把自我掺进去,它就变成了内在的、主观的身份危机。
书里的原话:「很多人常常会把赚钱的仓位出清,而赔钱的仓位却死抱不放。这是因为他们把赚钱和赔钱看做是自己智力或自我价值的表现……这就是混淆了金钱价值和自我价值。」
翻译成工程师语言:
- 你上个月写的服务,那是一段代码。代码烂,是个客观事实,像「这个灯泡是坏的」一样,不指向任何人。
- 但 2014 年那段祖传代码,如果注释里留着前任的名字、或者干脆是你自己三年前写的——它就不再只是一段代码。动它,等于宣判当初写它的人是错的。而如果那个人是你自己,宣判对象就是你。
判罚一旦从「代码烂」升级到「我烂」,大脑就不会再按工程逻辑处理这件事了。它启动的是另一套程序。
那套程序:绝症五阶段
吉姆·保罗发现,交易员面对巨额亏损的心理过程,和库布勒-罗斯研究的绝症病人面对死亡的心理过程,惊人地一致。五个阶段,一个不少:
「这代码没毛病,是调用方用错了」
「哪个天才写的这坨」——git blame 到自己,愤怒加倍
「先打个补丁,等下个大版本一起重构」
打开文件看两眼,叹口气,关掉。年复一年。
线上炸了 / 老员工离职带走知识 / 被迫重写
书里最狠的一句注脚,是赔钱者最常说的那句话:「我现在不能弃守,因为已经亏太多了。」你听听,这是不是也是你对着那个模块说过的话——「现在不能动,牵扯的业务太多了」。
注意那个回环箭头,它才是屎山越长越高的真正机制:每次打补丁(阶段③的讨价还价)都提供了一次虚假的缓解,让你跳回阶段①的否认。吉姆·保罗的原话:「每次短暂回升,都让他一再重复这些阶段,而在此过程中亏损也越来越大。」交易员等的是反弹,工程师等的是「下个版本有空」。
为什么偏偏是代码下不去手:市场永不关窗
还有一个机制,解释了为什么这类困局总发生在代码上,而不是别处。
吉姆·保罗把活动分成两类:个别事件和连续过程。赌一场球、掷一次骰子,是个别事件——终场哨响,输赢结算,你想否认都没得否认。而市场是连续过程:投注窗口永远不关,你可以一直不卖、一直加仓、一直告诉自己「还没卖就不算赔」。
书里的原话:「那个仓位可能正在赔钱,但你会告诉自己,还没卖掉就不算赔钱。」
软件项目是什么?连续过程的极端形态。没有终场哨。没有强制结算日。sprint 永远有下一个,需求永远在加,「重构它」的决议可以无限期地不被验证。一个永不关窗的赌场,配上一个把代码当自己的工程师——祖传代码就是这么炼成的。
解法:给连续过程造一个人工结算点
病根找到了——问题不在判断力,在于没有一个逼你结算的机制。那解法就反着来:自己造结算点。三个可操作的:
1. 开始之前,先写好「终止标准」。交易世界里这叫 kill criteria:在下单之前就白纸黑字写好「什么情况下认赔离场」。迁移到重构上:立项当天写下「什么情况宣布这次重构失败、回滚、放弃」。比如:「双写运行 4 周,性能无提升或故障率未降 → 回滚,结论:问题在架构不在实现。」写在动手之前,因为那时候的你还没被自我绑架,是全场唯一清醒的裁判。
2. 把「对错」降级成「优劣」。书里有句话值得贴在显示器上:「日后等尘埃落定再回头来看,决策是有优劣之别,但没有所谓的对错。」重构失败不等于你错了,就像一次好的决策也可能亏钱。它是成本,不是审判。这句话同时送给 code review:评审的对象是代码的优劣,不是人的对错。
3. 先啃最难的骨头。评估「要不要重构」时,人会本能地先做简单的部分——先写个新脚手架、先加个测试——每一步都感觉「有进展」。X 实验室(Google)管这叫「先建基座」:基座谁都能建,但建基座制造的只是进步的错觉,还顺手制造了新的沉没成本。先去验证最难的那块(那个最绕的并发逻辑、那个说不清的业务规则),猴子驯不了,基座白建。
冷水也得泼
这套心理学不是万能钥匙,泼三点冷水:
第一,分清「不敢动」和「不该动」。有的祖传代码是业务知识的活化石——里面藏着没写进文档的税务规则、和某个大客户的口头约定。不动它不是心理问题,是理性判断。判断标准很朴素:如果没人说得清它为什么这么写,先补文档和特征测试;说得清、且理由已失效,才轮到本文的心理学出场。亏损心理学解释的是你明知该动却动不了手,不背「一切保守主义」的锅。
第二,书的样本是 n=1。吉姆·保罗的故事发生在 1980 年代的期货交易所,杠杆、结算机制都变了,回忆录部分有文学渲染。但第 6、7 章的心理机制部分建立在库布勒-罗斯和行为科学的研究上,这部分耐久。引用时心里有数。
第三,别拿它攻击别人。这套框架最容易被滥用的姿势,是拿去 Diagnosis 同事「你就是沉没成本谬误」——别忘了书的第一课:把判断变成对人的审判,恰恰是病根本身。
我的判断
祖传代码问题,一半是技术债,一半是心理债。技术债有工具还(特征测试、绞杀者模式、双写迁移),心理债的工具就一个:在清醒的时候给未来的自己立法——终止标准写在前,结算日期定在前。
吉姆·保罗花了 40 万美元负债和父母双亡的一年才学会这件事,你花 6 分钟。
聊两句:你手头最不敢动的那段祖传代码——扣 1 是「别人写的,没人懂了」,扣 2 是「我自己写的,没脸看」。我先来:扣 2,2019 年一个「临时」脚本跑到今年还在跑。评论区扣数字就行,点赞最高的坑,下期我实际拆一次「怎么给不敢动的代码写终止标准」,全程记录。
往期全套在主页:LVS、双模型、ESP8266、PDF 转 EPUB、Cursor 三课、cangjie 拆书——这个系列叫「把复杂东西拆明白」。
