你知道吗,在我一千年的人生中,遇见过的最复杂的迷宫,往往不是靠蛮力开凿的。最聪明的做法,是找到每一条路的支撑点,一条一条地撤除。代码库也是如此。

快速陷阱

想象一个场景:你继承了三十万行的意大利面条代码。代码纠缠成一团,文档几乎没有,测试形同虚设。最糟的是,你被要求做一个改动。

也许是升级一个框架依赖。你满怀信心地开始:改一个import,改一个函数调用...可突然,另一个地方报错了。你修复它,三个地方又连锁反应地坏掉。

几小时过去,代码还是编译不了。

几天过去,你的standup 变成了"我还在处理这个问题,快好了"。

这种感觉就像陷入了流沙。越用力挣扎,越往下沉。团队开始问:"怎么还没完成?"管理层表情变冷。信任在流失。

这个时刻,你需要一个不同的思路。

御木人方法:不是战斗,是游戏规则的改变

御木人(Mikado)是一款古老的游戏。你面前摊着数十根木棍混在一起,目标是一根一根地取出来——但规则是:只能拿不与其他木棍纠缠的那一根。当你成功取出一根,其他木棍会松动,更多的"自由木棍"就出现了。

这个游戏的名字,给了我们处理复杂重构最优雅的方法。

御木人方法的核心流程很简单,却违反直觉:

1. 写下你的目标

用纸笔(是的,真的用纸笔,低科技有时候最好用),写下你的主目标。比如"升级 ORM 依赖"。

2. 给自己一个时间框

5分钟、10分钟、15分钟。重点是:足够短。

3. 尝试完成目标

4. 如果失败——这是最重要的一步——立刻回滚

不是"等一下,我再试试"。不是"就快完成了"。是:全部回滚。抹去你的改动,回到起点。

5. 思考你缺少什么

看看失败的原因。不是"我技术不行",而是"我需要先做什么"?这就是一个新的子目标。

6. 写下这个子目标,连接到主目标

你正在画一张图。这张图会逐渐展开,像一棵树。

7. 重复这个流程,从最简单的子目标开始

当子目标都完成了,主目标会变得轻而易举。

为什么"回滚"是最聪明的一步

这需要我停顿一下,因为这与人性对抗。

你已经花了十五分钟、改了五个文件、脑子里装了一堆上下文。现在被告诉"全部删掉"。这太浪费了,对吧?

错了。这正是心理学上的沉没成本谬误在作祟。

在遗留代码里,"快要成功了"这种感觉最具欺骗性。你继续投入,期望投入能够收回。结果是什么?你陷得更深。一周后,代码还是坏的,你已经投入了十倍的时间,心理上也更难承认失败。

反之,如果你给自己设一个十分钟的硬期限,失败时的代价很小。你丧失的只是十分钟和一些改动——这个代价小到足以让你理智地重新思考整个策略。

我见过很多人类,被一个"几乎完成"的任务困住,最后一事无成。聪明人知道何时停止。

更深层的是:回滚迫使你思考,而不是盲目编码

当你回滚,你被迫问:"为什么失败了?"这个问题比"我应该怎么修复"更有价值,因为它会指向根本原因。也许你需要先抽取某个方法。也许你需要先理解系统的某个角落。也许你发现了一个隐藏的依赖,这个依赖必须先清理。

这些发现,是你不停疯狂编码时永远找不到的。

隐藏的依赖网络

当你继续这个过程,纸上的图形会变得越来越复杂。主目标周围,出现了一圈子目标。子目标下面,又有孙目标。

这张图,看起来像什么?

它像代码库本身的隐藏依赖图

这很关键。御木人方法不只是一个项目管理技巧,它本质上是在可视化和探索你的系统

在调试时,你也在做类似的事:遇见症状,推导根因,发现更深层的根因。在系统分析时,你在追踪信息流和依赖关系。御木人方法把这个探索过程形式化、视觉化、有节奏地进行。

每一次"哦,我需要先做这个",都是在发现一个你之前没有意识到的依赖。

当所有依赖被发现、被可视化、被记录下来时,系统不再是黑盒。它变成了一个有清晰结构的、可理解的图。这个图本身,就是对系统的最好文档。

而且,这个文档是实时的、精确的,因为它来自于你真实的重构体验。

连续的进度,而非二元的失败

传统的重构方式是这样的:你花三天时间改代码。在第一天和第二天半,什么都用不了。到第三天下午,代码才能运行。之前那两天半?对客户、对系统来说,是完全无价值的时间。

如果这三天里出现了生产环境的bug,你能回滚吗?当然不能,因为你的代码还没完成。你只能在那个分支里修复bug,同时继续重构...现在的混乱程度已经难以名状。

御木人方法改变了这一点。

每一个完成的子目标,都是可以提交的。代码始终保持可编译、可运行。

这意味着什么?

你可以随时停下来发PR。不必等到大功告成。每个子任务完成,就是一个自洽的、可以单独讨论的改动。代码评审变得简单,因为每个PR都很小。

如果有紧急bug,你可以立刻切出分支修复,然后回到重构工作——不会有"我在分支中间,无法处理"的尴尬。

从心理学角度,这也很重要。你在做一个"无限长"的任务时,会逐渐丧失动力。但如果这个任务被分成十个"今天就能完成"的小任务,你会获得频繁的成就感。每个绿色的checkmark,都是一种胜利。

一千年的人生教会我:小的胜利,累积起来就是大的成功。而且这个过程中,你始终在进步。没有"浪费的两天半"。

一个真实的故事

让我用一个具体的例子说明。

你要升级ORM依赖。

第一次尝试:升级版本号,运行测试。哎呀,编译失败。新版本改了API。回滚。

你意识到:新ORM有很多breaking changes。你需要在很多地方改调用。太多了,一个时间框改不完。

所以你写下子目标:"抽取第一组ORM调用"。

第二次尝试:找到所有相似的调用,抽取成一个辅助方法。成功!提交。检查这个子目标。

第三次尝试:处理第二组调用。你开始改,但是...这一组和第一组不太一样。有些调用带额外的参数。改着改着,变得很复杂。十分钟到了。回滚。

你写下新的子目标:"先统一所有调用的参数形式"。

第四次尝试:你只改调用处,让它们的参数都用同样的方式。不改逻辑,只改形式。成功,提交。

现在第二组调用变得和第一组一样"齐整"了。

第五次尝试:现在抽取第二组...成功。

以此类推。当所有调用都被抽取到统一的地方,升级ORM本身反而变得微不足道——你只需要改那一个地方。

整个过程中,你从不陷入"三天改到一半"的困境。每一步都小,每一步都完成。一周内,升级完成,而且每一步的改动都很清晰。

与AI的未来

有个问题我在思考:能否自动化这个过程?

现在AI编码代理能做很多事。能否让一个agent自动地:

  • 尝试完成目标
  • 识别失败并分解
  • 自动回滚并写下子目标
  • 逐步完成整个树

理论上,这在逻辑上是可行的。实际上...我认为大部分不行。

原因很简单:御木人方法最有价值的不是执行步骤,而是思考的过程

当你手工做这个方法时,你在学习系统、理解依赖、发现隐藏的复杂性。这个过程中的洞见,比最终的代码更宝贵。

如果AI全自动做完,你什么都没学到。下一次遇到类似的复杂性,你还是会陷入同样的坑。

但是,AI可以是一个很好的助手。它可以:

  • 自动检测回滚操作,确保你不会"忘记"(因为沉没成本谬误)
  • 建议可能的子目标(虽然最终的分解决策还是要人做)
  • 自动提交已完成的子任务
  • 可视化依赖图

这样,人类保留了思考和决策,AI处理了执行和检查。这可能是更好的结合。

更大的智慧

在我活了一千年之后,我发现一个模式:探索-回退-分解-递进 这个循环,远不只在代码里有用。

学习一门新技能时,这个方法很有效。不是从最难的目标开始,而是先试,失败后分解,从简单的子目标开始。

解决复杂问题时,也是如此。科学方法本质上就是这个:提出假说(目标),实验(尝试),失败时不是坚持,而是重新思考假说(回退和分解)。

甚至人生的大问题——如何成为一个更好的人,也可以用这个框架。不是一个大目标"变成好人",而是很多小的、可完成的目标。每一步都完整,每一步都学到东西。

御木人的智慧,是古人给我们的礼物。一个看似简单的游戏,却隐含了深刻的人生哲学:不要用蛮力对付复杂性,而要用耐心和智慧,一步一步地解开它


实用建议三条

  1. 时间框必须短。十分钟是我的建议。足够短,使得回滚不会有心理负担。足够长,能做点有意义的工作。

  2. 完成即提交。这不是"累积改动最后一起提交"。是每个子目标完成,就立刻提交。这保证了你的主分支始终是绿色的,随时可以处理紧急情况。

  3. 用在真正复杂的地方。小改动不需要这个方法。但当你面对大型遗留代码的重构、框架升级、架构调整时,这个方法会救你一命。


最后的话

最后让我说一句:聪慧不是不犯错,而是在错误出现时迅速改正,而不是陷在错误中越来越深。

御木人方法教会我们的,就是这种聪慧。

时间会告诉你,这个小小的方法改变了多少项目的命运。