理解软件工程中的剃羊毛

剃羊毛的定义:一连串不相关的任务

剃羊毛描述了一系列相互依赖的任务,开发者必须完成一连串前置步骤才能实现最初的目标,往往最终会陷入与起点完全无关的任务。该术语由 MIT AI 实验室的博士生 Carlin Vieri 创造,灵感来源于《Ren & Stimpy Show》里一次奇怪的剃羊毛情节。

两个常见的例子说明了这种现象:

  • 工具链:要砍倒一棵树,需要一把斧子;如果斧子钝了,需要一块磨刀石;要得到磨刀石,需要前往特定的村庄;要旅行,需要一只牦牛;而使用牦牛之前,必须先把牦牛剃毛。
  • 家庭链:要洗车,可能会发现水管破了,于是要去 Home Depot,去那里需要 E‑ZPass 付桥梁通行费,获取通行证又要向邻居借,借到的通行证需要归还借来的枕头,而枕头上有牦牛毛,需要先把牦牛毛剃掉,最终又回到剃牦牛的步骤。

工程风险:从零开始构建

从零开始构建是专业工程中导致剃羊毛的主要动因。当开发者或管理者因认为现成方案缺乏定制性、想要证明技术能力,或误以为已有工具不满足特定需求而拒绝使用现成方案时,就会出现这种情况。

在预算和时间有限的生产环境中,这种做法风险极大。当工程师开始“剃羊毛”,即自行构建自定义基础设施而不是使用已有工具时,他们往往会失去对原始目标的关注,甚至导致项目彻底失败。

创造价值:为何剃羊毛令人满足

尽管存在生产力风险,剃羊毛对工程师来说常常具有内在的满足感。这种驱动力来源于弗雷德里克·P·布鲁克斯(Frederick P. Brooks Jr.)在《人月神话》(The Mythical Man‑Month)中指出的编程的几大核心乐趣:

  1. 纯粹的创造乐趣。
  2. 为他人创造有用事物的成就感。
  3. 构建复杂、相互嵌套的运动部件的魅力。
  4. 持续学习的乐趣。
  5. 表达媒介的灵活性。

案例研究:Donald Knuth 与 TeX

Donald Knuth 创造 TeX 是极端且成功的剃羊毛案例。1976 年,在准备《计算机程序设计艺术》第二版时,Knuth 发现现有的数字排版方案无法满足需求。为了解决写书的问题,他踏上了长达十年的从零构建完整系统的旅程。

为了实现排版一本书的最初目标,Knuth 创建了:

  • 一种新编程语言(WEB)。
  • 一种新编程范式(可读性编程,literate programming)。
  • 一种新行换算法(Knuth‑Plass 算法)。
  • 一套自定义字体(Computer Modern)以及用于定义矢量图形的语言(METAFONT)。
  • 一种与设备无关的输出格式(DVI)。

虽然书的出版被推迟了十年,但最终的系统成为了全球科学与数学排版的标准。

剃羊毛的教育收益

对于处于学习阶段的人来说,剃羊毛的效果尤为显著。深入研究从零构建系统所需的前置知识——例如布尔逻辑、逻辑电路、计算机体系结构和操作系统——往往比完成主要任务本身提供更多价值。即使最终项目未能完成,学习系统底层机制的过程也让这段努力变得值得。

Sources