人月神话(The Mythical Man-Month)
Table of Contents
- 1. 第一版序言(Preface to the First Edition)
- 2. 焦油坑(The Tar Pit)
- 3. 人月神话(The Mythical Man-Month)
- 4. 外科手术队伍(The Surgical Team)
- 5. 贵族专制、民主政治和系统设计(Aristocracy, Democracy, and System Design)
- 6. 画蛇添足(The Second-System Effect)
- 7. 贯彻执行(Passing the Word)
- 8. 为什么巴比伦塔会失败?(Why Did the Tower of Babel Fail?)
- 9. 胸有成竹(Calling the Shot)
- 10. 削足适履(Ten Pounds in a Five-Pound Sack)
- 11. 提纲挈领(The Documentary Hypothesis)
- 12. 未雨绸缪(Plan to Throw One Away)
- 13. 干将莫邪(Sharp Tools)
- 14. 整体部分(The Whole and the Parts)
- 15. 祸起萧墙(Hatching a Catastrophe)
- 16. 另外一面(The other face)
- 17. 没有银弹-软件工程中的根本和次要问题(No Silver Bullet – Essence and Accident in Software Engineering)
- 18. 再论《没有银弹》 (“No Silver Bullet” Refired)
https://book.douban.com/subject/1102259/
1. 第一版序言(Preface to the First Edition)
虽然写出来的是分离的章节,还是有一个中心的论点,特别包含在第2-7章。简言之,我相信由于人员的分工,大型编程项目碰到的管理问题和小项目区别很大;我相信关键需要是维持产品自身的概念完整性。
2. 焦油坑(The Tar Pit)
史前史中,没有别的场景比巨兽在焦油坑中垂死挣扎的场面更令人震撼。上帝见证着恐龙、猛犸象、剑齿虎在焦油中挣扎。它们挣扎得越是猛烈,焦油纠缠得越紧,没有任何猛兽足够强壮或具有足够的技巧,能够挣脱束缚,它们最后都沉到了坑底。
过去几十年的大型系统开发就犹如这样一个焦油坑,很多大型和强壮的动物在其中剧烈地挣扎。他们中大多数开发出了可运行的系统——不过,其中只有非常少数的项目满足了目标、时间进度和预算的要求。各种团队,大型的和小型的,庞杂的和精干的,一个接一个淹没在了焦油坑中。表面上看起来好像没有任何一个单独的问题会导致困难,每个都能被解决,但是当它们相互纠缠和累积在一起的时候,团队的行动就会变得越来越慢。对问题的麻烦程度,每个人似乎都会感到惊讶,并且很难看清问题的本质。不过,如果我们想解决问题,就必须试图先去理解它。
编程为什么有趣?作为回报,它的从业者期望得到什么样的快乐?
- 首先是一种创建事物的纯粹快乐。如同小孩在玩泥巴时感到愉快一样,成年人喜欢创建事物,特别是自己进行设计。我想这种快乐是上帝创造世界的折射,一种呈现在每片独特、崭新的树叶和雪花上的喜悦1。
- 其次,快乐来自于开发对其他人有用的东西。内心深处,我们期望其他人使用我们的劳动成果,并能对他们有所帮助。从这个方面,这同小孩用粘土为“爸爸办公室”捏制铅笔盒没有本质的区别。
- 第三是整个过程体现出魔术般的力量——将相互啮合的零部件组装在一起,看到它们精妙地运行,得到预先所希望的结果。比起弹珠游戏或点唱机所具有的迷人魅力,程序化的计算机毫不逊色。
- 第四是学习的乐趣,来自于这项工作的非重复特性。人们所面临的问题,在某个或其它方面总有些不同。因而解决问题的人可以从中学习新的事物:有时是实践上的,有时是理论上的,或者兼而有之。
- 最后,乐趣还来自于工作在如此易于驾驭的介质上。程序员,就像诗人一样,几乎仅工作在单纯的思考中。程序员凭空地运用自己的想象,来建造自己的“城堡”。很少有这样的介质——创造的方式如此得灵活,如此得易于精炼和重建,如此得容易实现概念上的设想。(不过我们将会看到,容易驾驭的特性也有它自己的问题)
编程固有的烦恼:其次,是由他人来设定目标,供给资源,提供信息。编程人员很少能控制工作环境和工作目标。用管理的术语来说,个人的权威和他所承担的责任是不相配的。不过,似乎在所有的领域中,对要完成的工作,很少能提供与责任相一致的正式权威。而现实情况中,实际(相对于正式)的权威来自于每次任务的完成。对于系统编程人员而言,对其他人的依赖是一件非常痛苦的事情。他依靠其他人的程序,而往往这些程序设计得并不合理,实现拙劣,发布不完整(没有源代码或测试用例),或者文档记录得很糟。所以,系统编程人员不得不花费时间去研究和修改,而它们在理想情况下本应该是可靠完整的。
3. 人月神话(The Mythical Man-Month)
在许多创造性活动中,往往很难掌握活动实施的介质,例如木头切割、油漆、电器安装等。这些介质的物理约束限制了思路的表达,它们同样对实现造成了许多预料之外的困难。由于物理介质和思路中隐含的不完善性,实际实现起来需要花费大量的时间和汗水。对遇到的大部分实现上的困难,我们总是倾向于去责怪那些物理介质,因为它们不顺应“我们”设定的思路。其实,这只不过是我们的骄傲使判断带上了主观主义色彩。
向进度落后的项目中增加人手,只会使进度更加落后。(Adding manpower to a late software project makes it later)
为什么缺乏合理的进度安排如此普遍
- 我们对于估算技术缺乏有效的研究
- 估算技术假设人和月可以进行交换
- 软件经理通常不会持续估算这项工作
- 对进度缺少跟踪和监督
- 当意识到进度的延缓下意识反应就是增加人力
对于软件任务的进度安排,以下是我使用了很多年的经验法则:
- 1/3 计划
- 1/6 编码
- 1/4 单元测试和构建测试
- 1/4 系统测试
特别需要指出的是,不为系统测试安排足够的时间简直就是一场灾难。因为延迟发生在项目快完成的时候。直到项目的发布日期,才有人发现进度上的问题。因此,坏消息没有任何预兆,很晚才出现在客户和项目经理面前。另外,此时此刻的延迟具有不寻常的、严重的财务和心理上的反应。在此之前,项目已经配置了充足的人员,每天的人力成本也已经达到了最大的限度。更重要的是,当软件用来支持其他的商业活动(计算机硬件到货,新设备、服务上线等等)时,这些活动延误出现即将发布前,那么将付出相当高的商业代价。
4. 外科手术队伍(The Surgical Team)
我常常重复这样的一个观点,需要协作沟通的人员的数量影响着开发成本,因为成本的主要组成部分是相互的沟通和交流,以及更正沟通不当所引起的不良结果(系统调试)。这一点,也暗示系统应该由尽可能少的人员来开发。实际上,绝大多数大型编程系统的经验显示出,一拥而上的开发方法是高成本的、速度缓慢的、不充分的,开发出的是无法在概念。
这就是小型、精干队伍概念上的问题:对于真正意义上的大型系统,它太慢了。设想OS/360的工作由一个小型、精干的团队来解决。譬如10人队伍。作为一个尺度,假设他们OS/360都非常厉害,比一般的编程人员在编程和文档方面的生产率高7倍。假定原有开发人员是一些平庸的编程人员(这与实际的情况相差很远)。同样,假设另一个生产率的改进因子提高了7倍,因为较小的队伍所需较少的沟通和交流。那么,5000/(10×7×7)= 10,他们需要10年来完成5000人年的工作。一个产品在最初设计的10年后才出现,还有人会对它感兴趣吗?或者它是否会随着软件开发技术的快速进步,而显得过时呢?这种进退两难的境地是非常残酷的。对于效率和概念的完整性来说,最好由少数干练的人员来设计和开发,而对于大型系统,则需要大量的人手,以使产品能在时间上满足要求。如何调和这两方面的矛盾呢?
5. 贵族专制、民主政治和系统设计(Aristocracy, Democracy, and System Design)
绝大多数欧洲的大教堂中,由不同时代、不同建筑师所建造的各个部分之间,在设计或结构风格上都存在着许多差异。后来的建筑师总是试图在原有建筑师的基础上有所“提高”,以反映他们在设计风格和个人品味上的改变。所以,在雄伟的哥特式的教堂上,依附着祥和的诺曼第风格十字架,它在显示上帝荣耀的同时,展示了同样属于建筑师的骄傲。
与之对应的是法国城市兰斯(reims)在建筑风格上的一致性和上面所提到的大教堂形成了鲜明的对比。设计的一致性和那些独到之处一样,同样让人们赞叹和喜悦,如同旅游指南所述,风格的一致和完整性来自8位拥有自我约束和牺牲精神的建筑师们,他们每一个人牺牲了自己的一些创意,以获得纯粹的设计。同样这不仅显示了上帝的荣耀,同时也体现了他拯救那些沉醉在自我骄傲中人们的力量。
我主张在系统设计中,概念完整性应该是最重要的考虑因素。也就是说为了反映一系列连贯的设计思路,宁可省略一些不规则的特性和改进,也不提倡独立和无法整合的系统,哪怕它们其实包含着许多很好的设计。
由于目标是易用性,功能与理解上复杂程度的比值才是系统设计的最终测试标准。 单是功能本身或者易于使用都无法成为一个好的设计评判标准。然而这一点被广泛地误解了。 操作系统 OS/360 由于其复杂强大的功能被它的开发者广为推崇。 功能,而非简洁,总是被用来衡量设计人员工作的出色程度。 而另一方面,PDP-10的时分系统由于它的简洁和概念的精干被建造它的人员所称道。 当然,无论使用任何测量标准,后者的功能与 OS/360 都不在一个数量级。但是,一旦以易用性作为衡量标准,单独的功能和易于使用都是不均衡的,都只达到了真正目标的一半。
我当然不认为只有结构师才有好的创意。新的概念经常来自实现者或者用户。 然而,我一直试图表达,并且我所有的经验使我确信,系统的概念完整性决定了使用的容易程度。 不能与系统基本概念进行整合的良好想法和特色,最好放到一边,不予考虑。 如果出现了很多非常重要但不兼容的构想,就应该抛弃原来的设计,对不同基本概念进行合并,在合并后的系统上重新开始。
类似的,我观察到外部的体系结构规定实际上是增强,而不是限制实现小组的创造性。一旦他们将注意力集中在没有人解决过的问题上,创意就开始奔涌而出。 在毫无限制的实现小组中,在进行结构上的决策时,会出现大量的想法和争议,对具体实现的关注反而会比较少。
6. 画蛇添足(The Second-System Effect)
想要成功,结构师必须注意
- 牢记是开发人员承担创造性和发明性的实现责任,所以结构师只能够建议而不能够支配
- 时刻准备为所制定的说明建议一种实现方法,同时准备接受其它任何可能到达目标的办法
- 对上述的建议保持低调和不公开
- 准备放弃坚持所做的改进建议
在开发第一个系统时,结构师倾向于精炼和简洁。他知道自己对正在进行的任务不够了解,所以他会谨慎仔细地工作。在设计第一个项目时,他会面对不断产生的装饰和润色功能。这些功能都被搁置在一边,作为“下一个” 项目的内容。 第一个项目迟早会结束,而此时的结构师,对这类系统充满了十足的信心,熟练掌握了相应的知识,并且时刻准备开发第二个系统。第二个系统是设计师们所设计的最危险的系统。而当他着手第三个或第四个系统时,先前的经验会相互验证,得到此类系统通用特性的判断,而且系统之间的差异会帮助他识别出经验中不够通用的部分。
这里第二个系统是相对于第一个系统而言的,在设计第一个系统时,工程师总是小心翼翼地在预算和功能之间进行合理的定夺,不加入一些花哨和毫无用的用途的功能,以期待在设计第二个系统时再加入。但是在设计第二个系统,这个系统成为了创造力宣泄的出口,各种庞大的无用的功能够加入。我对Stretch系统的印象是,从某种角度而言它是一个产品线的终结。如同早期的计算机程序一样非常富有创造性,设计非常复杂但是却异常地高效。不知道为什么,同时也感觉到,它粗糙浪费缺乏优雅,并且让人觉得必定存在更好的方法可以代替它(编写很多程序的时候我也有这种想法,总感觉必定有种更一致和优雅的设计)
7. 贯彻执行(Passing the Word)
8. 为什么巴比伦塔会失败?(Why Did the Tower of Babel Fail?)
现在,其实也是这样的情况。因为左手不知道右手在做什么,所以进度灾难、功能的不合理和系统缺陷纷纷出现。 随着工作的进行,许多小组慢慢地修改自己程序的功能、 规模和速度,他们明确或者隐含地更改了一些有效输入和输出结果用法上的约定。
产品负责人作为总指挥,技术主管充当其左右手。这种方法有一些困难。很难在技术主管不参与任何管理工作的同时,建立在技术决策上的权威。显然,产品负责人必须预先声明技术主管的技术权威,在即将出现的绝大部分测试用例中,他必须支持后者的技术决定。 要达到这一点,产品责任人和技术主管必须在基本的技术理论上具有相似观点; 他们必须在主要的技术问题出现之前,私下讨论它们; 产品责任人必须对技术主管的技术才能表现出尊重。另外,还有一些技巧。例如,产品责任人可以通过一些微妙状态特征暗示来(如,办公室的大小、 地毯、 装修、 复印机等等) 体现技术主管的威信,尽管决策权力的源泉来自管理。
9. 胸有成竹(Calling the Shot)
10. 削足适履(Ten Pounds in a Five-Pound Sack)
由于规模是软件系统产品用户成本中如此大的一个组成部分,开发人员必须设置规模的目标,控制规模,考虑减小规模的方法,就像是硬件程序员会设立元器件数量目标,控制元器件的数量想出减少零件的办法。同任何开销一样,规模本身不是坏事,但是不必要的规模是不可取的
创造出自精湛的技艺,精炼、充分和快速的程序也是如此。技艺改进的结果往往是战略上的突破,而不仅仅是技巧上的提高。 这种战略上突破有时是一种新的算法,如快速傅立叶变换,或者是将比较算法的复杂度从 n2降低到 n log n。更普遍的是,战略上突破常来自数据或表的重新表达——这是程序的核心所在。如果提供了程序流程图,而没有表数据,我仍然会很迷惑。 而给我看表数据,往往就不再需要流程图,程序结构是非常清晰的。
由于缺乏空间而绞尽脑汁的编程人员,常常能够从自己的代码中挣脱出来,回顾和分析实际情况,仔细考虑程序数据最终获得非常好的结果。实际上,数据的表现形式是编程的根本。
11. 提纲挈领(The Documentary Hypothesis)
我并不是很同意销售人员所吹捧的“完备信息管理系统”——管理人员只需在计算机上输入查询,显示屏上就会显示出结果。 有许多基本原因决定了上述系统是行不通的。 一个原因是只有一小部分管理人员的时间——可能只有 20%——用来从自己头脑外部获取信息。其他的工作是沟通:倾听、报告、讲授、规劝、讨论、鼓励。不过,对于基于数据的部分,少数关键的文档是至关重要的,它们可以满足绝大多数需要。
项目经理的任务是制订计划,并根据计划实现。但是只有书面计划是精确和可以沟通的。 计划中包括了时间、 地点、 人物、 做什么、 资金。 这些少量的关键文档封装了一些项目经理的工作。 如果一开始就认识到它们的普遍性和重要性,那么就可以将文档作为工具友好地利用起来,而不会让它成为令人厌烦的繁重任务。 通过遵循文档开展工作,项目经理能更清晰和快速地设定自己的方向。
12. 未雨绸缪(Plan to Throw One Away)
一旦认识到试验性的系统必须被构建和丢弃,具有变更思想的重新设计不可避免,从而直面整个变化现象是非常有用的。 第一步是接受这样的事实: 变化是与生俱来的,不是不合时宜和令人生厌的异常情况。 Cosgrove 很有洞察力地指出,开发人员交付的是用户满意程度,而不仅仅是实际的产品。 用户的实际需要和用户感觉会随着程序的构建、 测试和使用而变化。当然对于硬件产品而言,同样需要满足要求,例如新型汽车或者计算机。但物体的客观存在容纳和阶段化(量子化) 了用户对变更的要求。 软件产品易于掌握的特性和不可见性,导致它的构建人员面临永恒的需求变更。
很容易为上述层次建立相互一致的薪水级别。但要建立一致的威信,会困难一些。 比如,办公室的大小和布局应该相同。 秘书和其他支持也必须相同。 从技术线向管理同级调动时,不能伴随着待遇的提升,而且应该以“调动”,而不是“晋升” 的名义。相反的调整则应该伴随着待遇的提高,对于传统意识进行补偿是必要的。管理人员需要参与技术课程,高级技术人才需要进行管理培训。项目目标、进展、 管理问题必须在高级人员整体中得到共享。只要能力允许,高层人员必须时刻做好技术和情感上的准备,以管理团队或者亲自参与开发工作。这是件工作量很大的任务,但显然很值得!
系统软件开发是减少混乱度的过程,所以它本身是出于亚稳态的。软件维护是提高混乱度的过程,即使是最熟练的软件维护工作,也只是放缓了系统退化到非稳态的进程。
13. 干将莫邪(Sharp Tools)
14. 整体部分(The Whole and the Parts)
15. 祸起萧墙(Hatching a Catastrophe)
一天一天的进度落后是难以识别,不容易防范并且难以弥补。昨天某个关键人员生病了,无法召开某个会议。今天由于雷击打坏了大厦的供电变压器所有机器无法启动。明天因为工厂磁盘供货延迟了一周,磁盘例行的测试无法进行。这个列表可以不断延长,每件事情都使得某项活动延迟一天或者是半天,但是整体进度开始落后了,尽管每次只有一点点。
如何根据一个严格的进度表来控制项目?第一个步骤是制订进度表。 进度表上的每一件事,被称为“里程碑”,它们都有一个日期。 选择日期是一个估计技术上的问题,在前面已经讨论过,它在很大程度上依赖以往的经验。具体的里程碑是百分之百的事件。 “结构师和实现人员签字认可的规格说明”,“100%源代码编制完成,纸带打孔完成并输入到磁盘库”,“测试通过了所有的测试用例”。这些切实的里程碑澄清了那些划分得比较模糊的阶段——计划、编码、调试。
里程碑边界明显没有歧义,比它容易被老板核实更加重要。如果里程碑定义的非常明确无法自欺欺人的话,那么很少有人会弄虚作假。但是如果里程碑很模糊,那么老板就会常常得到一份与实际情况不符的报告。毕竟没有人愿意承受坏消息。这种做法只是为了起到缓和的作用,并没有任何蓄意的欺骗。好的里程碑对团队来说实际上是一项服务,可以用来向项目经理提出合理要求的一项服务。而模糊的里程碑式难以处理的负担。如果我们看到的,我们必须关注每一天的滞后,它们是大灾祸的基本组成元素。
当一线经理发现自己的队伍出现了计划偏离时,他肯定不会马上赶到老板那里去汇报这个令人沮丧的消息。 团队可以弥补进度偏差,他可以想出应对方法或者重新安排进度以解决问题,为什么要去麻烦老板呢?从这个角度来看,好像还不错。 解决这类问题的确是一线经理的职责。 老板已经有很多需要处理的真正的烦心事了,他不想被更多的问题打搅。 因此,所有的污垢都被隐藏在地毯之下。
但是每个老板都需要两种信息:需要采取行动的计划方面的问题,用来进行分析的状态数据。 出于这个目的,他需要了解所有开发队伍的情况,但得到状态的真相是很困难的。一线经理的利益和老板的利益是内在冲突的。一线经理担心如果汇报了问题,老板会采取行动,这些行动会取代经理的作用,降低自己的威信,搞乱了其他计划。所以,只要项目经理认为自己可以独立解决问题,他就不会告诉老板。有两种掀开毯子把污垢展现在老板面前的方法,它们必须都被采用。一种是减少角色冲突和鼓励状态共享,另一种是猛地拉开地毯。
减少角色的冲突。 首先老板必须区别行动信息和状态信息。他必须规范自己,不对项目经理可以解决的问题做出反应,并且决不在检查状态报告的时候做安排。 我曾经认识一个老板,他总是在状态报告的第一个段落结束之前,拿起电话发号施令。 这样的反应肯定压制信息的完全公开。不过,当项目经理了解到老板收到项目报告之后不会惊慌,或者不会越俎代庖时,他就逐渐会提交真实的评估结果。
16. 另外一面(The other face)
现实中,流程图被鼓吹的程度远远大于它们的实际作用。我从来没有看到过一个有经验程序员在开始编写程序之前,会例行公事的编制详尽的流程图。
17. 没有银弹-软件工程中的根本和次要问题(No Silver Bullet – Essence and Accident in Software Engineering)
所有软件活动包括根本任务-打造构成抽象软件实体的复杂概念结构,次要任务-使用编程语言表达这些抽象实体,在时间和空间限制内将它们映射成为机器语言。我认为软件开发中最困难的部分是规格说明,设计和测试这些概念的结构,而不是对概念进行表达和对实现逼真程度进行验证。从4个内在特性可以反映出来:复杂性,一致性,可变性和不可见性。
- 复杂性。数字计算机本身就比人类构造的大多数东西复杂,计算机拥有大量的状态,使得构思描述和测试非常困难。而软件系统的状态又比计算机的状态多了几个数量级。
- 一致性。开发最新的软件需要遵循各种接口,并且需要在一定程度上保持向后兼容。
- 可变性。对于机器,汽车等物体人们造出来就不会也不能够在进行修改,但是软件不一样,人们总是希望去修改软件,因此软件也被迫去被修改满足不同的需求。简而言之,软件产品扎根于文化的母体中,如各种应用,自然以及社会规律,计算机硬件等。后者持续不断地变化着,这些变化无情地强迫着软件也随之变化
- 不可见性。软件不可见也无法可视化,客观存在不具有空间的形体特征,剥夺了一些具有强大功能的概念工具的构造创意,限制了个人的设计过程也严重阻碍了思路相互之间的交流。
上述软件特有的复杂度问题造成了很多经典的软件产品开发问题。由于复杂度,团队成员之间的沟通非常困难,导致了产品瑕疵、 成本超支和进度延迟; 由于复杂度,列举和理解所有可能的状态十分困难,影响了产品的可靠性; 由于函数的复杂度,函数调用变得困难,导致程序难以使用;由于结构性复杂度,程序难以在不产生副作用的情况下用新函数扩充;由于结构性复杂度,造成很多安全机制状态上的不可见性。复杂度不仅仅导致技术上的困难,还引发了很多管理上的问题。它使全面理解问题变得困难,从而妨碍了概念上的完整性; 它使所有离散出口难以寻找和控制; 它引起了大量学习和理解上的负担,使开发慢慢演变成了一场灾难。
因此,现在是关注软件任务中的必要活动的时候了,也就是那些和构造异常复杂的抽象概念结构有关的部分。我建议:
- 仔细地进行市场调研,避免开发已上市的产品。
- 在获取和制订软件需求时,将快速原型开发作为迭代计划的一部分。
- 有机地更新软件,随着系统的运行、使用和测试,逐渐添加越来越多的功能。
- 不断挑选和培养杰出的概念设计人员。
因此,现在的技术中最有希望的,并且解决了软件的根本而非次要问题的技术,是开发作为迭代需求过程的一部分——快速原型化系统的方法和工具。软件系统的快速原型对重要的系统界面进行模拟,并演示待开发系统的主要功能。原型不必受到相同硬件速度、 规模或者成本约束的限制。 原型通常展示了应用程序的功能主线,但不处理任何如无效输入、 退出清除等异常情况。 原型的目的是明确实际的概念结构,从而客户可以测试一致性和可用性。
18. 再论《没有银弹》 (“No Silver Bullet” Refired)
就算《没有银弹》总体看来有些悲观,那么到底存在什么问题?是否爱因斯坦关于任何物体运动的速度无法超过光速的论断过于“黯淡” 或者“令人沮丧” 呢?那么哥德尔关于某些事物无法计算的结论,又如何呢? 《没有银弹》 一文认为“软件的特性本身导致了不大可能有任何的银弹”。 Tuski 在 IFIP 大会上发表了一篇论文作为出色的回应,文中指出:
在所有被误导的科学探索中,最悲惨的莫过于对一种能够将一般金属变成金子的物质,即点金石的研究。这个由统治者不断地投入金钱,被一代代的研究者不懈追求的,炼金术中至高无上的法宝,是一种从理想化理想和普遍假设中-以为事情会像我们所认为的那样-提取出的精华。它是人类纯粹信仰的体现,人们花了大量的时间和精力来认可和接受这种无法解决的问题。即使被证明是不存在,那种寻找出路和希望能一劳永逸的愿望依然十分强烈。而沃恩重的绝大多数总是很同情这些明知不可为而为之的人的勇气,因此它们总是能够延续。所以,将圆形变成方形的论文被发表,恢复脱发的洗液被研制和出售,提高软件生产率的方法被提出并成功地推销。
我们太过于倾向于遵循我们自己的乐观主义(或是发掘我们出资人的乐观主义)。我们太喜欢忽视真理的声音,而去听从万灵药贩卖者的诱惑。
因为OO和各种复杂语言的联系已经很紧密。 人们并没有被告诉OO是一种设计的方法,并向他们讲授设计方法和原理,大家只是被告知OO是一种特殊工具。 而我们可以用任何工具写出优质或低劣的代码。 除非我们给人们讲解如何设计,否则语言所起的作用非常小。 结果是人们使用这种语言做出不好的设计,没有从中获得什么价值。 而一旦获得的价值少,它就不会流行。
JPL 的 Van Snyder 向我指出,数学软件领域有着软件重用的长期传统:
我们推测重用的障碍不在生产者一边,而在消费者一边。如果一个软件工程师,潜在的标准化软件构件消费者,觉得寻找能满足他需要的构件,进行验证,比自行编写的代价更加昂贵时,重复的构件就会产生。 注意我们上面提到的“觉得”。它和重新开发的真正投入无关。
数学软件上重用成功的原因有两个: (1)它很晦涩难懂,每行代码需要大量高智商的输入;(2) 存在丰富的标准术语,也就是用数学来描述每个构件的功能。 因此,重新开发数学软件构件的成本很高,而查找现有构件功能的成本很低。 数学软件界存在一些长期的传统——例如,专业期刊和算法搜集,用适度成本提供算法,出于商业考虑开发的高质量算法(尽管成本有些高,但依旧适度) 等——使查找和发现满足某人需要的构件比其他很多领域要容易。 其他领域中,有时甚至不可能简洁地提出明确的要求。 这些因素合在一起,使数学软件的重用比重新开发更有吸引力
对软件重用问题,我们需要研究适当的学问,了解人们如何拥有语言。一些经验教训是显而易见的:
- 人们在上下文中学习,所以我们需要出版一些复合产品的例子,而不仅仅是零部件的库。
- 人们只会记忆背诵单词。语法和语义是在上下文中,通过使用逐渐地学习。
- 人们根据语义上的分类对词汇组合规则进行分组,而不是通过比较对象子集。