Notes.

读《人月神话》

2015-12-28 • ☕️ 1 min read

没有银弹 相信大多数人和我一样,第一听到《人月神话》的时候,心中不免会泛起疑惑:一部经典的软件开发著作怎么会配上一个浪漫神话故事的名字?是不是图书管理员搞错了,把小说放到了软件开发的书架上?不过,只要读过本书的第一章,就会恍然大悟:原来“人月”是软件开发估计和进度安排中使用的工作量单位。

这本书是 IBM 大型机之父佛瑞德·布鲁克斯的一系列经典文集。自出版以来,里面的“没有银弹”是引发争论最多的章节。不过我个人认为,虽然引发最多争议,但是这两章却是全书最重要、最深刻且最有价值的章节。即使从事的工作和软件工程无关,也应该认真阅读它。

首先我来解释一下什么是“银弹”。如果不了解西方的人狼传说和宗教信仰,可能会对这个词比较陌生,它的本意是一种由白银制成的子弹,是唯一能与狼人进行对抗的利器,引申为解决某一类问题的通用办法。举个简单的例子:对于二元一次方程,求根公式就是银弹;对于行星间引力的计算,牛顿的万有引力公式就是银弹。然而,对于软件开发来说,银弹是不存在的,用作者的话来说就是:“在未来的十年内,无论是在技术还是管理方法上,都看不出有任何突破性的进步,能够独自保持在十年内大幅度地提高软件的生产率、可靠性和简洁性。”

究其原因,其实主要是由软件开发的特点造成的。软件开发过程中遇到的困难其实可以总结为两类:根本性困难和次要性困难。而造成软件开发没有银弹出现的就是根本性困难。根本性性困难可以为分为:

1. 复杂性
2. 非一致性
3. 易变性
4. 不可见性

所谓复杂性,指的是没有任何两个软件部分是相同的(至少在语句的级别上)。如果有相同的情况,我们会把它们合并成供调用的子函数。在这个方面,软件系统和与计算机、建筑或者汽车大不相同,后者往往存在大量重复的部分。由于复杂度,团队成员之间沟通非常困难,导致了产品瑕疵、成本超支和进度延迟;由于复杂度,使列举(还远远不是理解)所有可能的状况变得非常困难,影响了产品的可靠性;由于函数的复杂性,函数调用变得困难,导致程序难以使用;犹豫结构性复杂性,函数难以在不产生副作用的情况下用新函数扩充;由于结构性复杂度,造成很多安全机制状态上的不可见性。所谓一致性,指的就是软件开发不像是物理学,无论是多么复杂的事物必定存在在某种通用的原理,或者在夸克中,或者在统一场论中。然而软件工程师却无法从类似的信念中得到安慰,因为软件的复杂度是随心所欲、毫无规则可言的,因为它来自若干必须遵守的认为惯例和系统,它随着系统的接口而变化,随时间的推移而变化。所谓的可变性指的是软件会经常面对持续变更的压力(就是需求的改变),这和例如建筑、汽车、计算机等行业是不一样的。因为软件是纯粹思维活动的产物,可以很容易地进行修改。这些经常变更的需求对软件开发人员来说简直就是噩梦,不得不为了完成新的需求而重新设计接口或者是推倒重建,这带来的后果就是项目延期、为了兼顾进度和功能而造成的设计上的缺陷。所谓的不可见性指的是软件无法用特定的形式可视化。它不像建筑行业有专门的平面设计图纸,汽车行业有三维建模模型等等。软件的客观存在不具有空间的形状特征,所以没有已有的几何表达方式。这种缺憾不仅限制了个人的设计过程,也严重阻碍了思维相互间的交流。

不过尽管这样,人们并没有放弃寻找提高软件开发效率的方法。既然根本性困难没有办法解决,那退而求其次,解决次要性困难。而且经过人们的反复实践和探索,在解决次要性问题上已获得一些突破:比如高级语言的发明等等。事实证明,高级语言在提高软件生产率、可靠性和简洁性上有显著成效,而单单对于软件生产率的提高至少有 5 倍。高级语言将编程人员从低级的位、寄存器、条件和分支中解放出来,转而关心更高层级的要素,消除了并不是程序所固有的整个级别的复杂度。

最后,作者却为我们针对概念上的根本问题提出了自己的见解:

1.	需求精炼和快速原型。
2.	增量开发——增长,而非搭建系统。
3.	聘用卓越的设计人员。

对于第一点,说的是在软件开发过程中,最困难的部分是需求的梳理,如果知道系统要做成什么样子,那么编码实现起来是很容易的。所以,软件开发人员为客户承担的最重要的职能是不断重复地抽取和细化产品的需求。事实上,客户并不知道自己需要什么。他们通常不知道哪些问题是必须回答的。并且,连必须确定的问题细节常常根本不予考虑,甚至只是简单地回答——“开发一个内斯我们已有的手工信息处理过程的新软件系统”——实际上都过于简单。所以,编码实现之前,让客户和设计人员之间进行多次广泛的交流沟通,是系统定义里面非常重要的一环。对于第二点,我们应该以增量的方式来开发系统,也就是说,系统首先应该是能运行的,不管它的功能有多么简陋,然后再一点一点的完善和扩展。这种开发方式对士气的推动是令人震惊的,当一个可运行的系统(即使是非常简陋的)出现在面前时,开发人员的热情就会迸发出来,因为他们能实实在在真真切切感受到自己对这个系统的贡献,这个系统是如何在自己的努力下一步步完善并趋于完美的。对于第三点,按照我的理解,一个产品的设计是很关键的。软件开发是一个创造性的过程,非常卓越的设计者产生的成功更快,更小,更简单,更干净,实现的代价更少。


Natumsol

Personal blog by Natumsol.
Note thoughts and experience.