跳转到主要内容

第 3 章 · 外科手术队伍

精干的小队伍跑不完大型系统,一拥而上又做不出概念一致性;Mills 的外科手术队伍是这两难之间的第三条路。

这一章的题记来自 Sackman、Erikson 和 Grant 的测量:“效率高和效率低的实施者之间个体差异非常大,经常能够达到数量级的水平。” 一句话就把"人"这个变量放到了台面上。

这一章讲了什么

作者的起点是一次会议上的常见说法:年轻的软件经理声称,他们喜欢由一流人才组成的小型精干队伍,而不是几百人的大团队——这里的"人"当然暗指平庸者。作者说自己常常有同感,但随即指出,这种幼稚的观点回避了一个很困难的问题:如何在有意义的进度安排内创建大型的系统?

先看测量数据。Sackman 等人的研究里,最好和最差的程序员在生产率上平均相差 10:1,在编程速度和空间占用上有 5:1 的差异;作者据此换算:两万美元年薪的程序员,生产率可能是年薪一万美元者的 10 倍。而经验和实际表现之间没有相互联系。既然个体差异如此之大,一个直截了当的方案就是——既然 200 人的项目里有 25 个最能干的经理,那就开除剩下 175 名程序员,让这 25 个人自己写。

作者立刻自己反驳。这个方案在实践中并不成立:25 人已大到至少需要两层管理(约 5 名管理人员),还要额外的财务、人员、空间、文秘和机器操作支持。更关键的是量级——OS/360 顶峰时有超过 1000 人参与,1963 到 1966 年设计、编码和文档工作花了大约 5000 个人年;如果真能用 200 人做完,需要 25 年。

那么换成理想的小队伍呢?作者做了个慷慨的假设:10 人团队,个个比一般人强 7 倍,再因为沟通少而叠加一个 7 倍因子。5000 ÷ (10×7×7) ≈ 10 年。一个在设计十年后才出现的产品,还有人会感兴趣吗? 于是两难显现:论效率和概念完整性,最好由少数干练的人设计与开发;论交付时间,大型系统需要大量人手。

Mills 的提议是第三条路:大型项目的每一部分由一个团队解决,但团队按外科手术的方式组建,而不是一拥而上。区别在于——不是把问题切开分给每个人,而是由一个人完成问题的分解,其他人向他提供支持。

作者由此给出了 10 人团队的角色清单:

角色职责
外科医生(首席程序员)定义功能与性能技术说明书、设计、编码、测试、编写文档;需要极高天分与大量系统知识
副手后备、思考者、讨论者、评估者;了解全部代码、研究备选设计;是外科医生的保险机制,但对代码不承担具体开发职责
管理员在人员、薪酬、办公空间上拥有决定权,但不在这类事务上浪费时间;小项目可同时服务两个团队
编辑依据外科医生的草稿或口述分析重组,维护多个版本,监督文档生成机制
两个文秘分别服务管理员与编辑,管理非产品文件与项目协作记录
程序职员维护产品库中的技术记录、机器码与可读文件的管理、状态日志与归档
工具维护人员保证基本服务可靠,并负责外科医生所需特殊工具的构建、维护与升级
测试人员既为各功能设计系统测试用例,也为日常调试设计测试数据
语言专家寻找简洁有效的语言用法解决晦涩问题,一人可服务 2–3 位外科医生

Mills 方案真正的关键,作者点得很明确:从"个人艺术"到"公共实践"的观念转换——把所有计算机的运行与产物向全体成员开放,把程序和数据显示为团队的所有物,而非私人财产。程序职员的专业化分工则把程序员从文书杂事里解放出来,同时让那些容易被忽视的杂事也有质量保障。

接下来是比较新旧两种队伍。10 人团队中 7 个专业人士在解决问题,而系统是一个人(最多两个人)思考的产物,于是在客观上达到了概念的一致性。与传统两人队伍的两点区别尤其重要:其一,传统队伍把工作切开,每人负责一部分的设计与实现;外科团队里外科医生和副手了解全部设计和全部代码,既省掉了空间分配、磁盘访问之类的摩擦,也保住了概念的完整。其二,传统队伍成员平等,出现分歧只能讨论和互相妥协,而工作与资源已经分解,分歧就会变成策略和接口上的不一致——比如"谁的空间被拿去做缓冲区";外科团队里不存在这种利益差别,观点不一致可以由外科医生单方面统一。作者的总结是:不分解问题,加上上下级关系,才换来客观的一致性。

最后是扩建。几百人的任务无法直接套用 10 人团队,做法是让 200 人干活,但只协调 20 个"外科医生"——因为每个部分的概念完整性由决定设计的人(原来的 1/7 或更少)负责到底。前提是必须有一个系统结构师自上而下做全部设计,并清晰划分体系结构设计与实现的界线。

我的判断

  • 这一章的论证结构本身就是示范:先立一个直觉(精干小队最好),再用数字把它压垮(10 年),最后给出新结构。比第 2 章更进一步的是,他没有停在"两难"上,而是给出了可操作的分工表。
  • 10:1 那份数据要谨慎对待。作者自己在括号里就写了"我怀疑这种现象是否普遍成立",而且样本是经验程序员的小组研究。用个体差异论证组织结构,风险在于把"人的问题"当成"结构问题"来解决——他后面提出的方案恰恰是靠结构(角色分工 + 单一决策者)而非靠选人。
  • 副手这个角色设计得最精妙也最容易被砍掉:他不承担具体开发职责,只做设计思考、讨论和评审,还要通读全部代码。这等于给关键技术决策配了一个专职的对立面和保险。现实里这个位置常被合并进"技术负责人"自己,于是保险机制名存实亡。
  • 我对"观点不一致可以由外科医生单方面统一"持保留态度。它在概念完整性上收益明确,但代价是把正确性押在一个人的判断上,而且作者没有讨论这位外科医生判断失误时怎么办。第 4 章讲概念完整性时会继续展开这一点。
  • 那份角色清单今天照搬会显得沉重(程序职员、两个文秘、专职语言专家都是 1960 年代的产物),但它的内核仍然锋利:把支持性工作从设计者身上剥离开,让一个人专注于概念,其余人围绕他做放大。今天的形态是自动化工具链和 Agent,而不是文秘和程序职员。

和我手上的工作有什么关系

  • 我现在的开发形态恰好落在这个谱系的极端:1 个"外科医生"加若干个承担支持职能的 Agent——构建、测试、文档、检索都是我之外的自动化角色,我不需要和它们开会,也不存在接口妥协。这一章实际上为这种编队提供了理论依据:支持职能可以很多,但做概念的只能是一个人
  • “副手"是这套编队里我目前最缺的角色。我的流程里没有专职的评审者,只有事后自己复查。按这一章的思路,成本最低的补法是让一个独立的 Agent 只做设计评审与反例构造,且不给它开发职责——这样它的立场才是对立的。
  • “程序职员"今天对应的是制品管理和可追溯性:版本、构建产物、状态日志、索引。我的站点的 bin/build.sh、CI 门禁、docs/sessions/ 记录,本质上就是在补这个角色,只不过用脚本和仓库代替了专人。
  • 20 个外科医生协调 200 人的比例(1:10)给了我一个粗糙的检查尺度:当一个项目里做概念决策的人超过十分之一,架构一致性就开始危险了。

一句话记住

小队伍输在交付时间,大队伍输在概念一致性;出路不是折中人数,而是换一种编队——让一个人负责全部概念,其余人的职责是放大他,而不是分摊问题。