没有银弹

《没有银弹：软件工程的本质性与附属性工作》（No Silver Bullet—Essence and Accidents of Software Engineering）是IBM大型电脑之父佛瑞德·布鲁克斯发表的一篇软件工程论文。这篇文章最早是他在1986年都柏林IFIP研讨会的受邀论文。隔年，电机电子工程师学会《Computer》也转载了这篇文章，并配上《伦敦狼人》等电影剧照作为说明，同时加入〈终结狼人〉的附注，带出“只有银弹才能解决问题”的现代寓意。文章强调，软件的复杂性是本质性的，因此真正的银弹并不存在；所谓“没有银弹”，指的是没有任何单一技术或方法，能在十年内让软件工程生产力提升十倍。

## 摘要

所有软件开发都包含本质性工作（essential task）和附属性工作（accidental task）。前者是建立由抽象软件实体构成的复杂概念结构，后者则是用程式语言把这些抽象实体实作出来，并在空间与速度限制下，将程式对应到机器语言。

如果附属性工作占比不到全部工作的9/10，那么即使把附属性工作完全消除，也无法让整体开发效率提升一个数量级。过去软件生产力的大幅进步，多半来自移除人为障碍，例如严苛的硬件限制、难用的程式语言，以及上机时间（machine time）不足等，这些因素都会让附属性工作变得更困难。

## 问题之所在－银弹与软件专案

佛瑞德·布鲁克斯在《没有银弹》中写道：

在民俗传说里，狼人是最令人恐惧的怪物之一，因为它们会突然从一般人变成可怕的怪兽，所以人们一直想找到能一枪解决狼人的银弹。

软件专案也常有类似情况（尤其从不懂技术的管理者角度来看）：平时看起来单纯，却可能很快变成时程延误、预算超支、品质不佳的怪兽。因此，人们总希望有一种银弹，能像硬件成本快速下降那样，有效降低软件开发成本。

但我们预期，从现在起十年内不会出现任何银弹。无论是技术或管理，都不会有某个单一重大突破，能保证在生产力、可靠度或简洁性上带来一个数量级的改善。

不过，这种怀疑不等于悲观。虽然不会有单一重大突破（而且这也不符合软件本质），仍有许多值得期待的创新正在发展。只要持续推进、扩散并善用这些做法，整体上仍可能达到一个数量级的进展。捷径没有，但稳定累积会有效果。

人类克服疾病的第一步，是用细菌说（germ theory）取代恶魔说（demon theory）与体液说（humours theory）。这让人们放下对奇迹解法的期待，改为靠按部就班的卫生改进与习惯养成来推动进步。软件工程面对的情况也是如此。

《没有银弹》主张，在未来十年内（自1986年发表起算），不会有任何单一软件工程突破，能让程式设计生产力提升一个数量级。不过，作者后来认为这个假设已不再成立。

假设软件开发总工作量为10，其中本质性工作占1、附属性工作占9。若能完全消除附属性工作，总工作量就会降到1，此时可视为开发效率提升一个数量级（由10降到1，即10倍差距）。

## 软件开发的困难

布鲁克斯把软件开发的困难分成两类。这篇论文的核心观点是：复杂的软件工程问题无法用单一简单方法解决。他认为软件开发真正的难点在概念架构的规格制定、设计与测试，而不是表达方式本身，或对表达方式的精确检验。

- 本质性（essence）：软件在概念（conceptual）建构上的先天困难，也就是如何从抽象问题发展出具体解法。
- 附属性（accident）：把概念构想实作到电脑上时遇到的困难。

布鲁克斯指出，附属性（accident）和附属的（accidental）常被混用。这个词源自亚里士多德的古老用法。在这里，accidental不是指“偶然发生”或“意外不幸”，而是更接近“伴随的”或“次要的”。

### 造成本质性困难的原因

布鲁克斯认为，附属性困难会随着工具改进而逐步减少，但本质性困难最难解决，因为大部分工作都在人的思考过程中进行，能直接帮上忙的工具有限。他列出以下几项：

- 复杂性（complexity）：软件要处理的问题通常牵涉到计算步骤，这是一种人为的、抽象的智能活动，本身就很复杂。
- 隐匿性（invisibility）：还没做完的软件看不见，就算用图示来说明，也常常没办法把结构讲清楚，造成沟通上的困难。
- 配合性（conformity）：在大型软件里，各个子系统的界面必须互相配合。但随着时间和环境变化，要一直保持一致并不容易。
- 易变性（changeability）：软件运作的环境包含人、法规、硬件、应用领域等等，这些因素都会不断变化。

### 过去的突破解决了附属性的困难

#### 高阶语言

高阶语言的主要作用，是让程式不必被大量底层细节绑住。抽象程式关心的是函式、资料型别、执行顺序、讯息传递等概念；但机器码实际处理的是位元、暂存器、条件、分支、通道、磁盘等底层元素。高阶语言把程式需要的概念具体化，同时隔离底层细节，等于移除了与程式本质无关的一层复杂性。

#### 分时技术

分时（time-sharing）技术解决的是即时回应问题。有了分时，系统互动更连续，开发者在思考时较能维持对整体脉络的掌握。分时技术的效益也有上限：它主要改善系统反应时间，当反应时间短到人类几乎无感（约十分之一秒）后，再加速的实际差异就不大。

#### 统一的开发环境

Unix和Interlisp是最早被广泛使用的整合软件开发环境，普遍被认为让生产力提升数倍。它们处理附属性难题的方式，是透过完整程式库、统一档案格式、管道（pipe）和过滤器 (Unix)（filter）等机制提升软件可共用性。概念上的构造因此更容易被呼叫、传递或套用到其他场景。这项突破后来也推动了工具软件发展，因为新工具只要遵守标准规格，就能用在多种程式上。

## 寻找银弹

Ada和其他高阶语言的进展

程式语言Ada是1980年代的通用型高阶语言。Ada不仅反映了语言概念的演进，也实作了多项支持现代设计与模组化的特征。相较于语言本身，Ada更被重视的是其设计理念：模组化（modularity）、抽象资料型别（abstract data type）、阶层式结构（hierarchical structure）。

物件导向程式设计

相较于当时其他流行技术，物件导向程式设计（object-oriented programming）被许多软件工程研究者寄予更高期待，达特茅斯学院的Mark Sherman指出，有两个不同的概念我们必须小心地加以分辨，从名称上就可以看出这两个概念的不同：抽象资料型别和阶层式型别。后者也被称为类别（class）。所谓抽象资料型别，其概念就是一个物件的型别应该由一个名称、一组适当的值和一组适当的操作方式来定义，而不是以它储存的结构来定义，这部分应该是要被隐藏起来的，例如Ada的包裹（package，使用私有型别）或Modula的模组（module）。

- 人工智能
- 专家系统
- 自动化程式设计
- 视觉化或图形化程式设计
- 软件的验证
- 环境与工具
- 工作站

## 评价回响

虽然《人月神话》引发许多讨论，但争议相对较少；《没有银弹》则引来更多反对意见，包括寄给期刊主编的信件，以及后续持续出现的书函与短评，其中相当一部分都在反驳“不会有任何特效药”的主张。

1990年，Brad Cox发表〈银弹存在〉（"There Is a Silver Bullet"），主张可用可再利用（reusable）、可替换组件的方法来处理概念本质性的问题。Glass、Vessey和Conger在1992年的论文中指出，有充分证据显示，关于银弹这类议题的研究仍未停止。

### Harel的分析

David Harel在1992年的一篇文献《紧咬银弹》（"Biting the Silver Bullet"

）中，对《没有银弹》做了细致分析。Harel认为《没有银弹》和1984年Parnas《战略防御系统软件面面观》都写得过于悲观，因此尝试补充较正向的一面，并在副标题中提出“让系统开发走向一个光明的未来”。

就Harel的认知，他认为造成《没有银弹》悲观的原因有三点：

- 本质性和附属性的二分法。
- 对每一个可能的银弹采取个别单独评论的方式。
- 只预测10年，这对“预期任何重大的突破”而言，并没有足够长的时间。

Harel还提出一项假想实验：假设《没有银弹》的主张不变，但发表时间改为1952年而非1986年。他使用归谬法（reducto ad absurdum），反驳从附属性中硬性切分出本质性的做法。

### Jones的观点

Caper Jones曾提出一个重要观点，最早出现在一系列非正式纪录中，后来收录于书中，也被数位与布鲁克斯通信的人提及。《没有银弹》和多数论文一样，把焦点放在生产力，也就是每单位软件输入成本能产生多少输出。Jones则主张：“把重点放在品质上，生产力会随之而来”。他认为，凡是成本过高、时程落后的专案，都会把大量额外时间花在找出并修正规格、设计与实作错误上。Jones也提出资料显示，缺乏系统化品质控制，与时程延误灾难之间有强烈相关性。

Caper Jones认为，若两份同等的Cobol程式都花10年编写，但其中一份采用结构化方法、另一份没有，最终效果可相差3倍。

## 外部链接

- No Silver Bullet: Essence and Accidents of Software Engineering, by Frederick P. Brooks, Jr.
- No hay balas de plata: Lo esencial y lo accidental en la Ingeniería del Software, by Frederick P. Brooks, Jr.
- 论银弹的存在