​ 自1975年出版以来,软件工程大师Frederick Brooks编写的《人月神话》便在软件工程领域占据着举足轻重的地位。如代序的Dave Wang博士在2002年所提到的,“回首软件工程近40年的发展,Jackson哀叹软件行业普遍缺乏专业性,充满了业余人员,“手中有一个锤子,看到什么都是钉子”,谁都可以开发性命攸关的软件”。

​ 21世纪,在互联网上良莠不齐的软件/应用/系统泛滥的今天,书中内容也仍然值得每个软件行业从业者参考和反思。

​ 下面将讲述该书带给我的一些思考。

苦恼的焦油坑

​ 对于想要从事软件工程的人来说,编程行业应该是有趣的。因为开发软件是一个创造的过程,开发者可以灵活的根据自己的思考,将脑海中抽象的想象转化为实实在在的工具,用以解决部分人的实际问题。这个过程所产生的满足感将会持续推动着开发者不断学习,然后创建出更加完备的软件,以满足更多人的需求,形成强大的正反馈。

​ 而软件行业也通常被形容为焦油坑,当工程趋于复杂,参与人员越来越多的时候,软件开发的过程将越发混乱,需要由他人设定目标、提供信息和资源。开发者也需要依赖于他人开发的程序,这些往往是难以控制的,需要花费更多额外的时间来研究和学习,耗费更多成本。并且创造性的活动也总会伴随着重复简单的劳动,例如寻找bug,编写测试等等。前期概念设计上的不完善和日积月累的需求和目标将会使得软件架构越来越庞大,最后成为一个焦油坑,越是挣扎,越是深陷其中。

​ 在项目开发中,我们通常称前人的代码为“屎山”,正是统一设计的缺乏,庞大的系统架构,难以修改的模块关系,过时的外部依赖,以及由于开发人员理解、水平不同产出的风格各异的代码构造出了这样一个不太优雅的词语。一代又一代的开发者便只能在焦油坑中苦恼和挣扎。

欺骗性的人月神话

​ 在软件工程管理中Man-Month人月的概念具有很强的误导作用。作为一个度量单位,人月顾名思义,就是指完成一个任务所需的人力和时间,是传统工程中的惯用思维。这个概念暗示了人员数量和时间是可以相互替换的,十个人两个月能完成的工作,二十个人一个月就能完成。用人月作为衡量一项工作的规模是一个危险和带有欺骗性的神话。设想在小说创作,电影拍摄等创造性劳动中,不同作家完成不同小说章节拼凑成一篇小说,不同导演摄影师设计不同电影片段拼凑成一部电影,最后的作品肯定不会呈现出好的效果。

​ 软件开发终究是创造性的脑力劳动,而不是劳动密集型的传统工程,团队扩大后将会带来更多的培训成本和交流成本以及任务分解的成本,由于个体差异,还会创造出新的bug。软件开发中往往伴随的都是非线性的投入产出关系。因此,作者指出,向落后的项目中增加人手只会使进度更加落后。进度出现问题的最有效方法仍然是消减任务,与其交付10个不可用的功能点,还不如交付5个优先级高的功能点。

​ 所以,在实际项目设计过程中,就需要意识到软件项目并不是一个关于人月的神话,不要用人月去规划软件开发的子任务,避免乐观地认为“一切将运转良好,每一项任务仅花费它应该花费的时间”,并且需要留有大量的时间计划,做好业务的拆分,保证每个人都不需要和其他人员有着深度的关联,讨论出合理的时间进度。不要把软件开发的大部分时间都分配给编写代码,而应该向作者所建议的那样1/3计划、1/6编码、1/4构件测试以及1/4的系统测试

可行的解决方案

如何作者根据自己的经验,也给出了自己的一些建议,下面根据我的理解总结了

外科手术队伍

​ 不同的程序员的效率完全不同,正如现在互联网企业会很严格的在招人时区分科班和非科班的区别,更不要说程序员个人的编程水平的区别。相同工作时间以及收到同样的培训的情况下,优秀的专业程序员的工作效率是较差程序员的十倍。

​ 但是一味的堆砌人员数量并不会有效提升开发的效率,因为开发成本的主要影响因素是人员之间相互的沟通和交流,以及沟通不当所引起的不良成果。所以系统应该由尽可能少的人原来开发,但小而精干的队伍会导致一些大型系统的开发周期被大幅度拉长,造成取舍的矛盾。

​ 所以大型项目的每一个部分都由一个团队解决,并且像外科手术团队那样构件。每个人在自己的专业领域针对某个职能从头负责到底。民主和平等并不是团队组建需要考虑的因素,团队应该延续一种英雄式的编程风格,主要的程序员决定项目的大部分内容,其他人成为副手,完成各种细节性的工作。这样既能获得由少数头脑产生的产品的逻辑完整性,又能通过多人协作提高效率,并且减少沟通的工作。所以互联网企业宁愿花几倍的工资去招聘高级开发人员,而不是去招聘更多的一般程序员。

完整概念设计

​ 在系统设计中,概念完整性应该是最重要的考虑因素,为了实现它,必须实行所谓的贵族专制,让少量的人员,也就是负责人来决定整体的软件架构,并且尽可能地将它灌输到团队每个人的脑海中,从而保证了整个项目开发的完整和一致性以及长期可维护性。

​ 也就是说,系统的每个模块基于同一套标准进行开发,系统的耦合程度,代码规范,接口的参数,函数的命名,依赖的基本框架,使用的库以及各种版本等等,都需要有明确的规范,并且需要保证在整个开发周期设计理念从头到尾都是保持一致的,团队逐渐形成一种约定俗成的默契。

​ 概念的完整性取决了系统使用的难易程度,其中的规范和纪律是对行业有益的,尽管某些程序员的创新会被忽略,但是软件开发并不是一个人的工作,需要更多考虑工程的一致性和可维护性,有一些构想并不兼容于整个系统,将其整合进现有系统中将会遇见极其负责的问题。

避免画蛇添足

​ 很多产品经理,负责人,架构师常常会过度设计,耗费一些没有必要的工时完成使用率并不高的功能。特别是在有了以往系统的经验时,开发第二个系统的时候会带着之前的信心,往第二个系统添加很多之前没有的功能和想法,想要将自己熟悉的技术发挥到淋漓尽致,但常常会忘记一些技术已经与当前系统发生了冲突。

贯彻执行和文档化

​ 作者推荐使用手册作为产品的外部规格说明,规定和描述了用户所见到的每一个细节,避免了用户看不见的事务。手册往往会重复许多基本要素,读起来枯燥乏味,但是精确比生动更加重要。对于一些琐碎的问题,保证这些问题的处理的一致性绝对不是一件无关紧要的事情,如果不统一规范将会带来额外的沟通成本以及导致一些无谓的bug。

​ 另外,开展会议有益于负责人掌握最新动态,每个人都可以提出问题和意见,然后讨论解决问题,最终达成共识,给出迅捷的结论,使得。从而有利于培养团队良好的沟通氛围,并且保证沟通渠道通畅,从上到下达成正式和详细的一致,然后解决问题,减少沟通成本。