跳转到主要内容
依人相的月光集市
← 返回首页2026-04-14· 约 3 分钟

忒修斯之船与代码重构:每一行都换过之后,它还是同一个项目吗?

一个古老的问题

普鲁塔克在《希腊罗马名人传》中记载了一个问题:雅典人保存了忒修斯从克里特岛返航的那艘船。随着时间推移,船上的木板逐渐腐朽,人们就用新木板替换旧的。一块一块地换,直到有一天,船上每一块木板都已经不是原来的了。

那么,这还是忒修斯的那艘船吗?

如果你是程序员,你对这个问题一定不陌生——只不过你管它叫"重构"。

代码中的忒修斯之船

想象一个运行了五年的项目。第一年用的 JavaScript,第三年开始逐步迁移到 TypeScript。React Class Component 一个一个改成 Hooks。REST API 慢慢替换成 GraphQL。Redux 被 Zustand 取代。Webpack 换成 Vite。测试从 Mocha 迁移到 Vitest。

五年后,你翻遍整个代码库,找不到一行是 v1.0 时期写下的代码。Git blame 显示最老的一行代码也只有六个月历史。

那么,这还是那个项目吗?

大多数人会说"当然是"。用户没变、域名没变、功能在持续演进、git 历史是连续的。这种回答对应哲学上的 "连续性理论"——身份不在于物质组成,而在于变化的连续性。只要每次改动都是渐进的,整体身份就得以保持。

但事情没那么简单

Thomas Hobbes 给忒修斯之船加了一个刺激的变体:如果有人把替换下来的旧木板收集起来,重新组装成一艘船——哪艘才是忒修斯的船?

在软件世界里,这种事真的发生过。

Node.js 的创建者 Ryan Dahl 后来创建了 Deno,用 Rust 重写了运行时,修复了他认为 Node.js 中的设计错误,但保留了核心理念——服务端 JavaScript 运行时。从某种意义上说,Deno 就是那艘用"旧木板"重新组装的船。

又比如,当一个核心开发者离开一个项目,带着所有的设计理念和架构思路去创建了一个竞品——灵魂走了,躯壳留下了。哪个才是原来的项目?

一个程序员的回答

我觉得软件项目的身份不在于代码本身,而在于三样东西:

1. 意图的连续性。 这个项目解决的核心问题没变,它就还是它。从 jQuery 到 React 再到 Server Components,前端框架的代码翻了几番,但"让构建 UI 更容易"的意图始终如一。

2. 社区的记忆。 项目的身份很大程度上存在于使用者的集体记忆中。大家说"Linux 内核"的时候,不是在指某一行具体的代码,而是在指一个由无数人共同维护和记忆的持续实体。

3. 变化的可追溯性。 Git 历史就是忒修斯之船的航行日志。只要每一次变更都有记录、有上下文、有理由,这条变更链本身就构成了项目的身份。

所以下次有人质疑"这还是原来那个项目吗"的时候,你可以理直气壮地说:

git log --oneline | wc -l

只要这个数字大于零,它就还是那艘船。