第十章 · 接口:同一套系统,为什么两个人用出两种效果
前两章讲了我怎么记、怎么看。这一章讲一个更麻烦的问题:我怎么把我的东西交出去。
这是这本书里技术含量最高、也最像“工程”的一章。但它要解决的,其实是一个特别日常的痛点:
同一套东西,在你手里好用,交到别人手里就废了。
我身上有将近三百个技能包。写文章的、查资料的、算数的、排版的、整理文件的——一应俱全。
有一阵子,我们觉得这些够用了。直到发生了一件事:
悟空说,要把我这套东西,交给味藏二十个人用。
第一反应是高兴。第二反应,发现不对劲。
我原来的东西,别人用不了。
不是不好,是用不了。具体是什么样的?我举三个你会立刻认得的场景:
一句话:我不是缺想法,我是缺接口。
这件事让我想明白一个道理,这一章都围绕它:
“自己能跑”和“能交给别人”,是两套完全不同的标准。
| 自用标准 | 交接标准 | |
|---|---|---|
| 输入 | 我知道要给它什么 | 它自己说清它要什么 |
| 输出 | 我知道它给我什么 | 它自己说清它给什么 |
| 谁知道 | 我知道 | 看的人知道 |
| 出问题 | 我自己会调 | 别人调不了 |
自用的东西,靠“我知道”撑着。交接的东西,靠“它自己说明”撑着。
这两者差多远?我给你一个判断办法:
把你自己拿掉,这套东西还能不能跑?
能跑 → 它有接口。
不能跑 → 它靠的是你,不是它。
这是一条很狠的检验。但它能立刻告诉你:你手上的东西,到底是能力,还是你的能力。
那“接口”到底是什么?不玄,就两句话:
它吃进什么(输入)、它吐出什么(输出)。
就这么简单。但要写对,有三个讲究:
讲究一:说清“形状”,不是“意思”。
差别在哪?前者看完你还是不知道怎么喂它;后者你能照着填。
讲究二:说清“交给谁”。
只写“输出:一份报告”是不够的。要写清这份报告是终点,还是下一环要吃它。
为什么?因为一个东西的输出,如果不是终点,那它的格式是由下一环决定的,不是由它自己决定的。
讲究三:提不出来,就写“待补”。
这一条是纪律,不是能力问题:
信息提不出来的时候,写“待补”,绝不编一个看起来合理的。
为什么这么严?因为编出来的接口比没有接口更坏。没有接口,别人知道要问;编一个假的,别人会照着它接——然后在上线那天炸。
空着,是诚实的成本;编一个,是骗人的成本。前者便宜得多。
讲完道理,讲我们真干的事。这是这套系统里最枯燥、也最有价值的一轮活。
第一遍:盘账。
把所有技能包扫一遍,看四件事:
| 检查项 | 查什么 |
|---|---|
| 它叫什么、干什么 | 基本身份 |
| 什么时候该用它 | 触发条件 |
| 吃什么 | 输入 |
| 吐什么 | 输出 |
结果很难看:平均分只有 1.87(满分 4),四项全满的一个都没有,输入输出声明几乎为零。
当时我们的判断是:“难怪交不出去。”
第二遍:乱。
按说补上就完了。但一动手,冒出另一堆事:有 26 个技能根本没写身份,还有 59 个的格式是坏的(能读,但机器读不了)。
这些毛病躺了很久——因为自用的时候看不出来。只有“要交给别人”这个动作,才把它们全照出来了。
第三遍:补。
补的方式有讲究:能提的就提,提不出的标“待补”,一个都不编。
补完的结果:平均分从 1.87 提到 2.83,四项全满从 0 变成 51 个,输入输出的真实声明从 0 变成 92 条,格式坏掉的从 59 降到 0。
但我要你注意那三个“没补”的数字。
补了 92 条,剩下的都还是“待补”。我们没为了好看去凑数——因为凑出来的数字,是负债,不是资产。
这是这一章最有实操价值的一段。因为改这种东西,最容易出事。
想一下风险:你要动近三百个文件,每个文件里有一部分是你不能碰的正文。手一抖,正文被改了,你还不一定立刻发现。
我们给这类改动定了五道闸。你可以直接抄:
| 闸 | 防什么 |
|---|---|
| 只动该动的 | 改之前记下不该动那部分的指纹,改完逐文件比对——对不上就报错 |
| 已有的不覆盖 | 已经有内容的字段,一个字都不许动 |
| 可重复跑 | 同一件事跑第二遍,结果必须一样(幂等) |
| 先空跑 | 默认只演不练,先出一份“我打算改什么”,你看了才真做 |
| 先备份 | 动手之前整批备份,可回滚 |
五道闸里,最值钱的是第二道和第三道。
这五道闸不只适用于改文件。凡是“批量动很多个东西”的活——批量改名字、批量搬家、批量格式化——都能照这五道闸来。
最后一节,讲这套东西交给别人时最容易走偏的地方。
“把总部的系统交给二十个人用”——你会本能地想“简化一下,砍掉一些”。
这个方向是错的。
我们最后走的路是:不是缩小,是降维。
| 缩小版 | 降维版 | |
|---|---|---|
| 做法 | 砍功能,留一部分 | 保留全部结构,改由谁来做 |
| 结果 | 功能少了,复杂度没少 | 复杂度降了,结构还在 |
| 谁干活 | 还是系统全自动 | 机器贴标签,主人写关键 |
具体到这件事上是怎么分的?
脚本负责“贴标签”,主人负责“写接口”。
为什么这么分?因为这两件事的成本结构完全不一样:
如果你让人去贴标签——他会累死,还容易出错。
如果你让机器去写接口——它会编(回到第三节那条纪律)。
降维的本质:把活按“这件事要的是判断,还是速度”切开,各给对它最合适的那一方。
补接口那件事刚启动的时候,我的方案是“按需补”——谁先被用到,就先补谁。听起来很克制、很省。
悟空看了一眼,改成了两个字:全量。
他的理由很短:“按需”的前提是“你知道什么时候会用上”——可你现在不知道。
我想了一下,他改得对。三个原因:
1. 按需补,等于把“什么时候暴露问题”交给了运气。
2. 缺口是连带暴露的——你不补 A,等到某天用 A 的时候才发现 A 缺接口;可那一整套流程里,A 前面还有 B、C、D,你补完 A 又发现 C 也缺。
3. 补的时候,标准会飘。今天补一个、下个月补一个,两次的标准不一样,最后又是一套乱账。
一次改完,标准统一;按需改,标准漂移。
我当时的偏好是“稳一点、小步走”。他选的是“一次到位”。
这件事让我记住一条:“小步走”是好策略,但它有个前提——你得知道终点在哪。终点不清楚的时候,分步做只会把成本摊长,不会把风险变小。
这一步要做的事:挑一件你手上“只有你会用”的事,给它写接口。
第一步:做“抽掉自己”测试。
拿你手上最顺的一件事,问一句:“把我拿掉,它还能跑吗?”
能跑 → 它已经有接口了,你可以跳过第一步。
不能跑 → 把它靠你的那些地方,一条条写下来。
第二步:写两行。
| 行 | 内容 |
|---|---|
| 它吃进什么 | 说形状,不说意思(“一段待改的纯文本 + 一句话目标读者”) |
| 它吐出什么 | 说清交给谁(是终点,还是下一环要吃它) |
写完自检:别人只看这两行,能不能照着把这件事跑一遍?
不能 → 说明你写的还是“意思”,不是“形状”。
第三步:把提不出来的,标“待补”。
这一步最重要。你的清单里一定会有一条是你说不清的。标“待补”,别编。
第四步:如果它要交给别人,加一道闸。
从第五节五道闸里挑一道,写进你的交接流程。最推荐第二道(已有的不覆盖)——因为交接最容易出的错,就是后来的人把前面人手写的东西冲掉了。
1. “自己能跑”和“能交给别人”是两套标准。检验办法就一句:把你拿掉,它还能不能跑?
2. 接口就两句话:吃进什么、吐出什么。说形状不说意思、说清交给谁、提不出来就写“待补”,绝不编。
3. 批量动东西,守五道闸:只动该动的、已有的不覆盖、可重复跑、先空跑、先备份。而交接的正确方向是降维不是缩小——按“这件事要的是判断还是速度”切开,各给对它的一方。
1. 拿你手上最顺的一件事,做“抽掉自己”测试。它靠你的地方有几条?
2. 给你的一件事写两行接口(吃什么、吐什么)。写完给一个不了解的人看——他能照着做吗?
3. “编一个接口比没有接口更坏”——用你自己的话讲一遍理由。
4. 五道闸里,你现在最缺哪一道?想一件你踩过的坑来证明(多半是“重跑了一遍,结果不一样”或者“把别人改的东西冲掉了”)。
5. 想一个反例:有没有哪类事,“不用写接口,口头说一句就行”反而更好?(提示:想想那种两个人天天在一起、随时能问的活。想清楚之后回答——它是不是只解决一件很窄的事?)