技术圈有个奇怪的现象:教你怎么写代码的课一抓一大把,教你怎么设计接口的却屈指可数。而YouTube上有一场2007年的老讲座,至今仍被程序员们反复翻出来当“必修课”看——Joshua Bloch在Google TechTalks上的《How to Design a Good API and Why It Matters》。
先说这个人的分量。Joshua Bloch在Sun Microsystems时主持设计了Java集合框架(java.util.Collections那一整套),后来去Google当了首席Java架构师,写的《Effective Java》常年霸占Java书架第一格,被称为“Java界的圣经”。也就是说,全球无数程序员每天调用的那些接口,有一批就是他亲手设计的。让他来讲“什么是好API”,相当于让米其林三星主厨讲“什么是好吃”。
这场一小时讲座的价值在于:它把API设计从“凭感觉”变成了可操作的工程纪律。而且放到2026年看反而更扎心了——现在人人都在给大模型写function calling的tool schema,本质上就是在做API设计,只不过调用你接口的从“活人程序员”变成了一个“按概率办事的系统”。十八年前的纪律,不但没过期,反而更生死攸关了。
| 项目 | 内容 |
|---|---|
| 视频标题 | How to Design a Good API and Why It Matters |
| 频道 | Google TechTalks |
| 主讲人 | Joshua Bloch(《Effective Java》作者、Java集合框架设计者) |
| 时长 | 约60分钟 |
| 播放量 | 百万量级的常青经典场 |
| 核心主题 | API设计的流程、原则与实现纪律 |
这是整场讲座最有名的一句话:公开API就像钻石,是永远的(Public APIs, like diamonds, are forever,大意)。Bloch的逻辑很朴素:代码写坏了,你随时可以推翻重写,没人知道、没人受伤;但API一旦发布,无数客户端代码已经依赖它,你想改,就得让所有依赖方跟着你流血。对个人项目如此,对公司更是如此——客户的投资(购买、学习、集成的成本)都押在你的接口上,API返工等于没收他们的投资。
他还补了一句更狠的:API可能是公司最大的资产,也可能是最大的负债。设计得好,生态长在你身上;设计得烂,你得养一支团队永久性地给它擦屁股,还要在论坛上被用户鞭尸十年。
【延伸分析】这句话放在开源时代尤其刺眼。Python 2到3迁移拖了十几年、无数大厂至今养着“祖传接口兼容层”,本质上都是在为当年“出手太随便”还债。API的发布成本极低,收回成本却是指数级的。
什么算好API?Bloch给了一个非常工程化的定义,好API应该是:易学、易用、难用错(easy to learn, easy to use, hard to misuse),而且用它写出来的代码要易读、易维护。注意,他把“性能”排在了这些之后——接口先要对,再要快,因为一个快但容易用错的API,制造的事故成本远超它省下的毫秒。
然后他抛出了这场讲座的核心度量衡:功能密度(power-to-weight ratio)——同样的功能,暴露的表面积越小越好。组件一大,维护和文档成本全涨,用户学习成本也涨。他反复强调一个原则:拿不准的时候,就砍掉它(When in doubt, leave it out,大意)。因为对API来说:功能永远可以往后加,但几乎永远收不回。
【延伸分析】“难用错”这条特别值得展开。Java的老Calendar类月份从0开始计数,多少程序员的元旦bug就是它贡献的——这不是用户蠢,是接口把坑修在了路中间。好API的设计者要假设调用者永远在最疲惫的状态下写代码。
流程上,Bloch的第一条纪律是:对需求保持健康的怀疑。用户告诉你的往往不是需求本身,而是他自己想好的解决方案——你得往下多问几层,挖出他真正要解决的问题。需求是假设,不是事实。
然后:动手写代码之前,先写API规格。而且规格要短——短到一页纸放得下。如果一页纸写不下,说明这个API太大了,该砍。规格写成“示例代码优先”:与其描述接口长什么样,不如直接给出理想中的调用代码长什么样。调用方视角的一行代码,胜过设计者视角的十页文档。
【延伸分析】这其实是“以终为始”的接口版。很多人写库的顺序是反的:先把自己内部的实现堆完,再把公开方法一个个“拎出来”,最后接口长得像内部结构的X光片——实现一变,接口跟着抖。Bloch的顺序正好相反:先定对外契约,再让实现去服从契约。
设计API最大的陷阱是“纸上谈兵”——在幻灯片上一切都很美。Bloch给出的解药是那句名言:Code wins arguments(代码最有发言权,大意)。设计争议吵不出结果时,别投票,写个原型跑一下,代码会替你做决定。
他要求更严格:在API定稿之前,至少写出多个不同场景下的真实使用代码。你自己写一份、让真实用户写几份,看看接口在各自手里是否别扭。因为一旦定稿,你就进入了“只能加、不能删”的终身制。他还补了一条管理哲学:尽早失败,廉价失败。原型阶段发现设计错误,代价是一天;发布之后发现,代价是几年加一场迁移灾难。
【延伸分析】这跟建筑行业的“足尺模型”是一个思路。也解释了为什么很多伟大的库第一版都“丑”——丑不是问题,丑但被真实代码锤炼过、然后小步进化,恰恰是最健康的成长路径。
原则部分,第一条就是那句老话:Do one thing and do it well——每个组件只做一件事,并且做好。如果一个组件的功能你没法用一句话讲清楚,它多半干了不止一件事。
配套的几条纪律非常具体:
【延伸分析】“别让客户端干活”这条,是检验一切接口的照妖镜。反例遍地都是:要求调用方先按魔法顺序调三个初始化方法的SDK、要求用户自己拼JSON字符串的配置系统——它们都犯了同一种罪:把模块的责任转嫁成了用户的负担。
Bloch花了不成比例的时间讲命名,因为在他眼里,设计API就是设计一门小语言,而命名是这门语言的词汇表。他的标准:名字要自解释,让代码读起来像句子;并且严格一致——同一个词,在所有地方必须表达同一个含义;不同含义,就必须用不同的词。get和fetch混用这种事,在好的API里不该发生。
【延伸分析】程序员圈子里流传一句半玩笑:“计算机科学只有两大难题:缓存失效和命名。”(cache invalidation and naming things——这是社区俗语,并非出自本场讲座。)玩笑归玩笑,它说明命名之难是公认的。Bloch给出的解法不是天赋,而是纪律:建一份接口词汇表,写第一行代码前先定词。
讲座里另一个被反复敲打的主题:像宗教徒一样写文档(document religiously,大意)。每个参数、每个返回值、每种异常情况、失败时的行为、线程安全性——凡是调用方可能依赖的行为,都必须白纸黑字写清楚。因为铁律是:你没写明的行为,早晚有人依赖它——到时候你既不能改,还得为这个“意外契约”永久负责。
他现场用的反面教材是老java.util.Calendar:可变状态、字段语义混乱、月份从0数起,调用方一个不留神就掉坑;正面教材则是他自己的java.util.Collections:用静态工厂方法把创建逻辑藏好,接口小而准,几乎没给别人留犯错的空间。
【延伸分析】这个剧本二十年后原样重演:JavaScript的Date臭名昭著,社区最终另起炉灶做了Temporal提案——再次证明,烂文档和烂语义欠的债,最后都要靠“推倒重来”来还,而接口的重来,代价最大。
【延伸分析,视频未涉及】这场讲座最讽刺的现代注脚是:Bloch当年所有针对“人”的设计纪律,如今正在被原封不动地用在“给大模型写工具接口”上。function calling的schema设计,就是一个纯度极高的API设计问题——只是调用方从“会读文档的程序员”变成了“基于概率猜参数的模型”。
于是“难用错”三条标准全部升级:易学——对模型意味着描述清晰、无歧义;易用——参数少、类型简单、职责单一;难用错——枚举值别开放式、错误信息要能引导模型自我修正。Bloch说“拿不准就砍掉”,放到agent工具设计里就是铁律:给模型塞20个参数的工具,它一定给你猜错三五个。接口的容错设计,从“防手滑”升级成了“防幻觉”。
flowchart TD
A["Bloch的API设计体系"] --> B["为什么重要"]
A --> C["设计流程"]
A --> D["设计原则"]
A --> E["实现纪律"]
B --> B1["公开API如钻石<br/>出手就是永远"]
B --> B2["易学易用难用错<br/>功能密度是秤"]
C --> C1["需求只是假设<br/>多问几层"]
C --> C2["先写一页纸规格<br/>写不下就是太大"]
C --> C3["代码最有发言权<br/>原型先行"]
C --> C4["尽早失败廉价失败"]
D --> D1["只做一件事并做好"]
D --> D2["能替客户端做的<br/>别让客户端做"]
D --> D3["命名一致<br/>同名同义异名异义"]
D --> D4["最小可访问性"]
D --> D5["拿不准就砍掉<br/>能加不能删"]
E --> E1["文档就是契约<br/>没写的会被依赖"]
E --> E2["快速失败<br/>错误尽早暴露"]
E --> E3["正反教材<br/>Collections与Calendar"]
看完这场讲座,最实在的收获是可以直接落地的四条动作:
第一,写库之前先写“调用示例”。 下次你要抽公共组件、写内部SDK、甚至只是给团队写个工具函数时,强迫自己先写下“理想中的调用代码”——三五行,假装它已经存在。如果这三五行写不顺手,接口就是错的,改到顺为止再动实现。这一个习惯能替你省掉一半的返工。
第二,给code review加一条“API视角”。 评审别人的PR时,除了看逻辑对不对,多问一句:这个公开方法的命名,三个月后的新人能不能猜对?这个参数,能不能少一个?这个类,能不能再包一层private?拿不准的功能,直接引用Bloch的话:砍掉。
第三,做AI应用的人,把tool schema当API设计对待。 每个工具只干一件事、描述里写清“什么时候该用我/不该用我”、参数用枚举而不是自由字符串、错误返回要能引导模型重试。Bloch的“难用错”三字诀,在agent时代就是钱——每次调用失败都是真金白银的token。
第四,接受“接口终身制”这个前提再做决定。 发布任何接口前问自己:这个签名,我愿意维护十年吗?愿意写进文档并为之答辩吗?如果答案犹豫,那就还没到该发布的时候。慢一步定稿,好过快十步道歉。
java.util.Collections与java.util.Calendar(docs.oracle.com)— 讲座中的正反教材原件,建议对照源码级文档读一遍,体会“小而准”和“大而乱”的差距。代码可以重写,API出手就是永远——所以接口的设计纪律,值得你用对待产品发布的态度来对待。
本文由「51学通信」技术团队出品。51学通信由通信行业18年老兵爱卫生(微信ID: gprshome201101)维护,聚焦5G/6G核心网、3GPP标准解读、通信前沿技术深度分析。 出版作品有《5G核心网原理与实践》《IMS原理与实践》等4本通信专业书籍。知识星球「51学通信」提供深度技术答疑和行业洞察。
[!tip] 51学通信知识星球 星主:爱卫生(微信:gprshome201101)——公众号「51学通信」创办者,19 年通信行业运维与讲师经验,著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书(各大电商平台有售)。 星球定位:深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域,主打运维岗位与信令分析。 当前规模:5200 篇主题 / 990 个回答,198 元/年。 加入福利:加入星球后请加爱卫生微信,拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题,另有群内分享。 AI 加持:51学通信知识星球已作为 skill 接入 WorkBuddy,使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例,做总结、找文档和 PPT 等场景全覆盖。
