《没有银弹:软件工程的本质性与附属性工作》(英语:)是IBM大型机之父佛瑞德·布鲁克斯所发表一篇关于软件工程的经典论文,原先是在1986年都柏林IFIP研讨会的一篇受邀论文,隔年电机电子工程师学会《Computer》也转载了这篇文章,他们用了几张《伦敦狼人(英语:Werewolf of London)》之类的电影剧照来当作说明,还加上了一段〈终结狼人〉的附注,用来引出非银弹则不能成功的(现代)传说。该论述中强调由于软件的复杂性本质,而使真正的银弹并不存在;所谓的没有银弹是指没有任何一项技术或方法可使软件工程的生产力在十年内提高十倍。
所有软件创作都包括了本质性工作(essential task)和附属性工作(accidental task)。前者是去创造出一种由抽象的软件实体所组成的复杂概念结构,后者则是用编程语言来表现这些抽象的实体,并在某些空间和速度的限制之下,将程序对应至机器语言。
现在,若跟本质性的工作相比,软件工程人员所做的事,还有多少算是花在附属性的工作上呢?除非附属性工作要耗费的心力超过全部工作的9/10,否则就算是将所有的附属性工作降至零,也无法将整个开发工作的轻松程度提升一个数量级。以往,软件生产力的重要进展绝大部分是来自于人为障碍的排除,像是严苛的硬件限制、难用的编程语言、上机时间(machine time)的不足等等,这些都是造成附属性工作益发困难的原因。
佛瑞德·布鲁克斯在《没有银弹》中提到:
在民俗传说里,所有能让我们充满梦靥的怪物之中,没有比狼人更可怕的了,因为它们会突然地从一般人变身为恐怖的怪兽,因此人们尝试着查找能够奇迹似地将狼人一枪毙命的银弹。
我们熟悉的软件项目也有类似的特质(以一个不懂技术的管理者角度来看),平常看似单纯而率直,但很可能一转眼就变成一只时程延误、预算超支、产品充满瑕疵的怪兽,所以,我们听到了绝望的呼唤,渴望有一种银弹,能够有效降低软件开发的成本,就跟电脑硬件成本能快速下降一样。
但是,我们预见,从现在开始的十年之内,将不会看到任何银弹,无论是在技术上或管理上,都不会有任何单一的重大突破,能够保证在生产力、可靠度或简洁性上获得改善,甚至,连一个数量级的改善都不会有。
然而,怀疑并非悲观,虽然我们预见不会有任何重大的突破,而且事实上,我相信发生这种重大突破也不符软件的本质,但是,仍然有许多令人振奋的创新正在进行当中,若能按部就班、持之以恒地予以发展、散布,并灵活运用的话,想必应该会得到一个数量级的进展。快捷方式是不会有的,但有志者事竟成。
人类能克服疾病的第一步,就是以细菌说(germ theory)淘汰了恶魔说(demon theory)和体液说(humours theory),正是这一步,带给了人类希望,粉碎了所有奇迹式的冀望,告诉人们进步是要靠按部就班、不辞劳苦而来,得在清洁卫生方面持续不断地投入心血,养成良好习惯,才是正道。如今,我们面对软件工程也是一样。
《没有银弹》主张并断言在未来的十年之内(从1986年文章发表后开始计算),不会有任何单一的软件工程上的突破,能够让程序设计的生产力得到一个数量级的提升。不过,作者认为这个假设现在已不再成立。
假设软件开发的总工作量为10,其中,本质性工作占掉1,附属性工作占掉9,那么改善附属性工作,将之消除,就可以把软件工作量减轻到1(因为附属性工作变成0),此时我们可以说,软件工作开发的轻松程度提升了一个数量级(因为由10进步到1,差10倍)。
布鲁克斯将软件开发的困难分为两类,这篇经典论文的核心论述通常被解释为复杂的软件工程问题无法靠简单的答案来解决。布鲁克斯相信软件开发真正的困难,是在于这种概念构造的规格制定、设计和测试,而并非在孜孜矻矻于它的呈现方式,以及测试该呈现方式的精确程度。
布鲁克斯提到,有某些地方已经被附属性(accident)和附属的(accidental)这些字眼给混淆了,这个字眼是出自于亚里斯多德的古老用法。就英语:accidental的这个字眼而言,他所指的并不是偶然发生的意思,也不是意外不幸的意思,而是比较接近伴随的或次要的意思。
布鲁克斯认为,附加性的困难会随着工具的改善而逐渐淡化,反而是本质性的困难最难以解决,因为大部分的活动是发生在人们的脑海里,缺乏有效的辅助工具。依照布鲁克斯的说法有下列几项:
高级语言达成了什么样的使命呢?它使程序不再陷入许多原来附属在程序里的复杂性。一支抽象的程序所包含的是一些概念的构造:函数、数据类型、先后顺序的关系,以及消息传递的方式,然而实际上,与机器代码攸关的其实是比特、寄存器、条件、分支、通道、磁盘等等。高级语言可以将抽象程序里所必要的构造予以具体化,并且避免掉所有更低端的东西,在这种情形下,它把跟程序内涵一点关系都没有的那一整层复杂性给去除了。
分时(time-sharing)技术所挑战的是另一个截然不同的难题,因为分时,确保了即时性,使我们得以持续保住脑子里对复杂的概观。分时技术所能贡献的底限也可以直接推算出来,由于其主要的效用就是缩短系统的反应时间,当这项时间趋近于零,并在某一点上跨越了人类所能够察觉到有系统反应时间存在的临界点,大约是十分之一秒,低于这个值,就不会再有任何效益了。
Unix和Interlisp是第一个得到广泛使用的集成软件开发环境,并且也被公认已将生产力提升了好几倍。这方面所挑战的附属性难题,就是借由完整的程序库、统一的文件格式、管道(pipe)和过滤器(英语:Filter (Unix))(filter),以促成软件的共享,于是,任何概念的构造在理论上都可以调用、传递和运用在另一个对象,而实务上,这点也很容易就可以办得到。这方面的突破随后也带动了整个工具软件的发展,因为每一个新工具只要用的是标准规格,就可以适用于任何程序。
编程语言Ada是1980年代的一个通用型高级语言。事实上,Ada不只是反映了在语言概念上的演进,同时也具体实现了一些助长现代设计与模块化概念的特征;也许,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年的一篇论文中就指出,有充分的证据显示,对银弹这种没有意义的研究仍尚未停止。
David Harel在1992年的一篇文献《紧咬银弹》("Biting the Silver Bullet")中,对已经发表的《没有银弹》进行非常仔细的分析。Harel认为《没有银弹》和1984年Parnas《战略防御系统软件面面观》这两篇都写得太过于绝望了,于是他针对这一点来阐述较为光明的一面,他的文章还用了个副标题是“让系统开发走向一个光明的未来”。
就Harvel的认知,他认为造成《没有银弹》悲观的原因有三点:
Harvel更提出了一项假想实验,他假定《没有银弹》的主张不变,只是发表的时间换做是在1952年,而非1986年。他这时用的是归谬法(reducto ad absurdum),用来反驳自附属性中切分出本质性的作法。
Caper Jones曾提出一个敏锐的见解,这个见解最初是写在一连串非正式的纪录中,后来出现在书上,几个与布鲁克斯通信的朋友也提到过。《没有银弹》就如同大部分的论文一般,都把焦点集中在生产力,也就是软件每单位的输入成本能得到多少输出效果。Jones则表示:“把重点放在质量上,生产力将随之而来”。他认为,只要是成本过高和时程落后的项目,都耗费了非常多的额外时间和工作在查找并修正规格、设计、实现中的错误。Jones并提出数据佐证,缺乏有系统的质量控制与发生时程落后的灾难,这两者之间有强烈的相关性。
Caper Jones相信,两份同等的Cobol程序分别花10年编写,但其中一份使用结构化的方法,另一份则否,那么所得到的效果将相差3倍。