本文翻译自 Use the Mikado Method to do safe changes in a complex codebase,原载于 Hacker News。
你接手了一个 30 万行的意大利面条式代码。现在该怎么办?
庞大、缺乏测试、文档缺失的代码库非常棘手。很难理清其中的逻辑关系。
在复杂的代码库中,你无法快速行动。
陷入遗留代码的流沙
问题是,雇你来就是要改这些代码的!你需要实现新的功能需求,或者修复一些 bug。
也许你决定要处理技术债务,重构那些遗留代码。也许你想在系统仍然在线服务客户的同时,改进它的架构。
但任何有价值的变更都会让你走上一条失败之路 😩
比如说你想升级 ORM(对象关系映射)依赖。你开始动手,但很快发现存在一些破坏性变更(breaking changes)。所以你需要修改代码库中的多处函数调用。为了让这更容易,你决定先重构,把这些调用提取到一个地方,这样只需要改一个位置。但要做到这一点,你首先需要适配每一个调用……
很快你就会发现自己陷入了流沙:每当解决一个问题,又会冒出两个新问题。
项目已经无法编译了。距离你上次提交代码已经过去好几个小时。连续几天,你的站会汇报听起来都是”我还在做,只需要再改几个东西”……
如果你正处在这种境地,你不是一个人!
而且有一种方法可以避免陷入流沙。它就是:Mikado Method(御柱方法)。
一种结构化的变更方法
核心思想听起来像是常识:
只有一种方法能吃掉一头大象:一口一口地吃。
在复杂的代码库中,小的变更很快就会变成一头大象。
如果你直接硬上,很可能会撞墙。会很痛苦。你会延期。客户和管理层会不高兴。信任会流失,而没有信任,你就很难获得管理层对必要重构工作的支持。
相反,把大象切成小块 🐘
具体流程
下面是你可以遵循的 Mikado Method 流程:
- 拿出一张纸。有时候低技术更好。这就是这样的时刻。
- 设定一个目标。写在纸上。放在顶部或中心都可以。留出空间给其他条目。
-
在时间盒内尝试达成目标。5分钟、10分钟、15分钟,随你便。保持相对较短。
- 如果失败了:
- 撤销你的变更。撤回你在时间盒内做的所有改动。重新开始很重要。
- 思考缺少什么。你需要先改什么才能让目标更容易达成?这就是你的子目标。
- 把它写在纸上,并与你试图达成的目标连接起来。
- 从第 3 步重新开始,处理你的子目标。
- 如果成功了:
- 提交代码。你肯定会在时间盒结束前完成,没关系,停止计时。
- 在纸上勾选已完成的目标。在心里庆祝一下。
- 从第 3 步重新开始,处理下一个未勾选的子目标。从你的 Mikado 图的叶子节点开始。迭代直到勾选完主目标。
- 如果失败了:
实际操作示例
让我们回到 ORM 依赖升级的例子。
首先,在纸上写下目标。画两个圈圈起来。这就是你的主目标!
主目标:「升级 ORM」
你尝试这么做。你升级了依赖,发现项目无法编译了。该死,你应该先读更新日志的!
好的,你读了更新日志,明白需要修改一些调用。说实话,这对单个时间盒来说改动太多了!
撤销你的变更。真的。撤销它。这很重要。🔥
然后,写下需要先做的事情。
如何在短时间盒内修改几个调用?简单:先提取这些调用,这样你就不需要在很多地方改。让升级本身变得快速!
新子目标:「提取 .query()」和「提取 .dump()」
重新开始。尝试在时间盒内提取第一个方法。
希望只有几个调用,而且它们都很相似。你可以在几分钟内完成任务。恭喜!
提交你的工作,勾选那个子目标,给自己鼓个掌。你离主目标更近了一步。
子目标「提取 .query()」已勾选 ✓
现在尝试处理另一个调用。你开始做,但没有上一个那么顺利 😩
几分钟后,停下来思考。缺少什么?什么能让这个变更像上一个一样简单?
也许你首先需要让每个调用看起来相似。
撤销你的变更。再次强调。我是认真的。
然后写下新的子目标。
新子目标:「适配 booking 中的调用」和「适配 cart 中的调用」
从一个叶子节点重新开始。迭代。
当它的所有子目标都被勾选后,处理一个目标应该就很容易了。最终,你让主目标变得简单了。
然后,直接做。升级你的 ORM 依赖。
最终,所有目标都被勾选了,包括主目标!🎉
恭喜!你刚刚实现了一个雄心勃勃的变更,而没有陷入代码库的流沙中。
掌握 Mikado 方法的三点建议
-
保持时间盒短。这样更容易撤销变更。这是避免沉没成本谬误的关键步骤。我发现 10分钟 是一个务实的折中方案。
-
勾选目标时就提交代码。这是一个检查点,让你离主目标更近。这意味着你可以随时停下来,开一个 PR,发布这些改进。你可能还没完成任务,但你让它变得更容易了。
-
在开始雄心勃勃的重构时使用这个方法。采取小步骤并保持代码处于可发布状态,会给你带来惊人的生产力。
为什么叫「Mikado」?
这是参考 Mikado 挑棒游戏。
你想移除的那根棍子就是你的 ORM 依赖升级。
它和几十根其他棍子缠在一起:恼人的依赖关系和你需要做的调整,才能让代码继续工作。
策略是先移除容易的棍子。那些没有缠住的。逐步地,你解开你的棍子。直到你可以拿到它而不破坏任何东西 🎉
甚至有一本深入讲解这个流程的书:The Mikado Method。

稍微练习一下,你就会擅长这个。
你会成为 一个高效得多的开发者!
关键要点总结
-
不要直接硬上大变更 — 复杂代码库中,大变更会引发连锁反应,让你陷入流沙
-
使用纸笔画图 — 可视化你的目标和依赖关系,低技术有时更有效
-
短时间盒 + 频繁撤销 — 10分钟一个周期,失败就撤销,避免沉没成本谬误
-
先解决前置条件 — 把大目标拆成小目标,从叶子节点开始逐个击破
-
每个小目标都提交 — 保持代码随时可发布,增量推进,随时可以暂停
-
像挑棒游戏一样思考 — 先拿容易的,逐步解开缠绕,最后才能安全拿到目标
这个方法特别适合处理技术债务和架构改进,推荐在实际工作中尝试!