大多数重写服务于工程师,而非业务
2026年6月30日 · 5分钟阅读 在某个夏天的几周里,我每天早上4点起床,重写我雇主已经支付别人编写的代码。它每天都在生产环境中运行,是用CakePHP构建的。我几乎对CakePHP一无所知,所以每个文件在我看来都错了。我知道Laravel,并且喜欢在其中工作。因此,在我的业余时间,我自作主张地逐步将其移植过来,逐个替换Illuminate包,直到旧框架被彻底淘汰。我们合并了它。我们在Laravel上开始了下一个项目。我从未一次提出过重写的理由,因为这对业务来说并不值得。这个应用程序为相同的用户以相同的速度完成了相同的工作。重写只改善了一件事:代码对我来说的感觉。这正是值得命名的模式。大多数重写响应的是工程师的需求——他们想学习的东西,令他们感到不悦的东西,在面试中看起来良好的东西——而不是支付薪水的公司。有效的代码是已经修复的所有错误的账本。反对重写的最有力论据不是所需的努力,而是记忆。在生产环境中运行了多年的代码是对每一个某人遭遇并安静修复过的错误的书面记录。奇怪的条件语句、那些值得怀疑的超时重试:大部分是伤疤组织,每个伤疤标志着你从未见过的事件。Joel Spolsky在2000年提出了这一观点,称全面重写是软件公司可能犯的最糟糕的战略错误。抛弃代码,你就丢弃了修复。然后你在生产环境中、在同样的用户面前再次遇到同样的错误。我曾经在一个已经超过十年的Perl系统上工作,也在一个大约同龄的自制PHP CMS上工作。两者看起来都与我今天编写的代码大相径庭。它们只是运行着。公司从未对此进行再投资,而这是正确的选择。代码早已为自己付出过代价,每一个安静的年份它保持着流量都是纯粹的回报。不熟悉并不等于错误 这是我在自己故事中遗漏的关键。我确信CakePHP代码是错的,但我实际上从未学习过CakePHP。不熟悉并不等于错误。当你不熟悉一个工具时,用它构建的每个事物看起来都是个错误,因为你尚未看到背后选择的原因。“这一切都错了”的感觉往往只是你尚未理解的声音。反之假设:在你之前的人并不是愚蠢的。他们做出的选择适合当时的用例和约束。代码以这种方式被塑造是有原因的,即使这个原因现在对你来说不再可见。触碰它是正确的选择 这一切并不意味着冻结一切。这是对“如果它没有坏”的懒惰解读,这就是你在2026年运行没有安全补丁的生命周期结束的运行时的原因。一些债务确实会到期。诚实的强制因素看起来是这样的——这并不是完整的列表,只是我不断遇到的:运行时或关键依赖项已经到了生命周期结束,有公开的CVE且没有升级路径。一人理解该系统,他们刚刚递交了辞呈。每个新功能的成本比应有的高出三倍,因为设计问题,你可以展示趋势。业务需要的某个能力当前的代码从未被塑造成能够增长。最后一点就是我现在的处境。我正在重写一个服务,一个AI编码代理正在做大部分的打字,因为我们需要它执行以前从未构建过的功能。代码是有效的。业务已经超出了它。这是一个有数字支持的理由。区分真正重写和面子工程的测试就是这么简单:你能给痛苦打上一个数字吗?一个CVE,一个速度税,你无法进行的招聘,一个你将错过的发布。如果没有数字出现,你得到的只是对风格的偏好。 AI让重写的打字变得便宜,但得到正确的难度依旧存在。 AI改变了这个逻辑,但并非大多数人所声称的那样。新的论点是,重写再次变得便宜:模型可以在一个下午移植整个模块,那为什么不让它呢?但打字从来不是重写的高成本部分。重新发现才是。一个代理在几分钟内生成替代方案。它不知道为何旧代码携带那个奇怪的超时,因为那个理由存在于2021年的Slack线程和没人从源头链接的事后分析中。因此,它生成了干净而合理的东西,去掉了伤疤组织。你发布它,然后你再次遇到旧的错误,而这次没有最初作者在修复它时所拥有的背景知识。快速生成忘记自己修复的代码并不是折扣。干净的版本也不会被人所青睐。今天的代码像一堆别人错误的原因在于它经历了现实的考验。AI编写的替代品也会遭遇同样的命运。在两年内,一名工程师打开它,无法看到它为何被这样塑造,并感受到重写它“正确”的相同冲动。更便宜的生成并不能结束这个循环。它使得这个循环更容易启动,更难以停止。
本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。
☕请我喝杯咖啡