书在一开头就提到了软件工程管理中的一个关键问题:人/月。在项目管理过程中,这个指标实际上是有一些误导作用的,给人的感觉是项目取决于两个关键因素,人和时间(月),而这两个指标仿佛看上去就是一个正比关系,增加人,减少月;减少人,增加月。于是就造成一种简单粗暴的项目管理办法,当项目进展受阻或者进度落后时,直接往项目中增加人手,仿佛这样就可以直接解决问题。而书中直接就针对这个问题指出:
“用人月作为衡量一项工作的规模是一个危险和带有欺骗性的神话”
并提出Brooks法则:"想进度落后的项目中增加人手,只会使进度更加落后。(Adding manpower to a late software project makes it later )"
这里背后的一个原因是,随着软件开发过程越来越成熟,很多人没有将软件开发当成一种创造性的脑力劳动,而逐步地将软件工程当成了劳动密集型的工程,软件规模和工作量是一种线性增长的模型。
即使是劳动密集型的工程,也不是一个简单的换算关系,设想建设一栋大楼,100个工人建一年,不是说36500人一天就可以搞定的。更何况对于软件工程这样一件含有大量创造性工作在内的脑力工程。
章节中提到,我们在进行工作量估算时,往往省略了团队规模扩大之后的一个重要事件成本——沟通成本。而沟通成本由两个部分组成:培训和相互的交流。每个成员需要进行技术、项目目标、总体策略以及工作计划的培训。这种培训是不能分解的,因此这部分增加的工作量随人员的数量呈线性变化。
上述提到的培训成本是线性的,还是可以接受的。而相互之间的交流成本更麻烦一些。一个大型、复杂的软件项目往往都是相互关联的,为了保证一个目标在团队之间达成一致,最坏情况下是每个部分必须分别于其他部分单独协作,则工作量按照n(n-1)递增。这是一个很可怕的增长。
也就是说,当团队增长到一定的规模后,新增人员带来的沟通成本会比开发成本都高的多,反而会拖累项目的进度。反过来也要求在软件设计之初做好业务的拆分,做到不需要每个人都需要和其他人员有深度的关联,在代码上也需要做好解耦的设计。当前流行的DDD、微服务、代码上的设计模式都是基于这样一个原则来试图解决问题。
而在软件项目开始之前就认识到 软件项目不是一个关于人月的神话,对软件工程抱有敬畏之心才是最重要的。
二. 团队组成
上面提到沟通工作量随着团队规模的扩大而呈指数级增长,而往往一个大型项目的工作量往往是很大的,需要同时由很多人的协作才能完成,对于这样一个问题,我们就很有必要考虑下如何处理了。
首先,书中提到:优秀程序员和较差程序员之间的生产效率有非常的差异,一个研究表明:最好的和最差的表现在生产率上平均为10:1,在编程速度和空间上具有5:1的惊人差异!简言之,20000美元/年的程序员的生产率是10000美元/年的程序员的10倍,反之亦然! 其实这个比较好理解,现实场景中也会经常碰到,一个业务经验和编程经验较差的程序员埋的坑,需要经验两倍于他的程序员花两倍的时间去填。如果这样的坑流转到了线上系统的话,花费的代价会更大。
因此,很多人都热衷于拥有一支小型,精干的队伍,由几位经验丰富的程序员组成,而不是几十上百人的“平庸”程序员。但是现实场景往往不允许:
大型系统的工作量巨大,如果是按照工作量估算的话,一支小型而精干的队伍可能在1-2年的时间开发出来,但是2年后,这个产品是否还能在市场上受到欢迎呢?
经验丰富的程序员在人才市场上往往都是可遇不可求,绝大部分都是“平庸”的程序员。
那么如何调和这两方面的矛盾呢?书的第三章提到了作者提到了由harlan mills提出的——“外科手术队伍”的团队:(这里先引用书中全部描述,个人对这段描述理解的不是很明白)
外科医生。mills称之为首席程序员,应该是类似于我们现在的首席架构师。对整个系统的完整性负责,包括技术和业务完整性。
副手。外科医生的后备,主要作用是作为设计的思考者,讨论者和评估人员。副手可以有多名,经常在与其他团队讨论有关功能和接口问题时代表自己的小组。了解所有的代码,研究设计策略的备选方案。可以不负责具体代码的开发。
管理员。他是外科医生的老板,必须在人员、薪酬、办公空间等方面具有决定权,但他绝对不能在这些事务上浪费任何时间。因而,他需要一个控制财务、人员、工作地点和办公设备的专业管理人员,该管理员充当与组织中其他管理机构的接口。 Baker建议,仅在项目具有法律、合同、报表和财务方面的需求时,管理员才具有全职责任。否则,一个管理员可以为两个团队服务。
编辑。外科医生负责文档的生成,出于最大透明度的考虑,他必须创建各种文档,无论是对内部描述还是外部描述。而编辑根据外科医生的草稿或者口述,进行分析和重新组织,提供各种参考信息和书目,对多个版本进行维护,并监督文档生成的机制。
两个文秘。管理员和编辑每个人需要一个文秘。管理员的文秘负责非产品文件和使项目协作一致。
程序职员。他负责维护编程产品库中所有团队的技术记录。该职员接受文秘性质的培训,承担机器码文件和可读文件的相关管理责任。所有的计算机输入汇集到这个职员处。如果需要,他会对它们进行记录或者标识。输出列表会提交给程序职员,由他进行归档和编制索引。另外,他负责将任何模型的最新运行情况记录在状态日志中,而所有以前的结果则按时间顺序进行归档保存。
Mils概念的真正关键是“从个人艺术到公共实践”的编程观念转换。它向所有的团队成员展现了所有计算机的运行和产物,并将所有的程序和数据看做是团队的所有物,而非私人财产。程序职员的专业化分工,使程序员从文书等杂事中解放出来,同时还可以对那些经常被忽视的杂事进行系统整理,确保了它们的质量,并强化了团队最有价值的财富——工作产品。上述概念显然考虑的是批处理程序。当使用交互式终端,特别是在没有纸张输出的情况下,程序职员的职责并未消失,只是有所更改。他会记录小组程序和私有工作拷贝之间的更新,依然控制所有程序的运行,并使用自己的交互式工具来控制产品逐步增长的完整性和有效性。
工具维护人员。现在已经有很多文件编辑、文本编辑和交互式调试等工具,因此团队很少再需要自己的机器和机器操作人员。但是这些工具使用起来必须亳无疑问地具备令人满意的反应和可靠性。外科医生则是对这些工具的服务是否充分可用的唯一评判人员。他需要一个工具维护人员,保证所有基本服务的可靠性,以及承担团队成员所需要的特殊工具(特别是交互式计算机服务)的构建、维护和升级责任。即使已经拥有非常卓越的、可靠的集中式服务,每个团队仍然要有自己的工具维护人员。因为他的工作是检查他的外科医生所需要的工具,而不是其他团队的需要。工具维护人员常常要开发一些实用程序,编制具有目录的函数库以及宏库。
测试人员。外科医生需要大量合适的测试用例,用来对他所编写的工作片段,以及对整个工作进行测试。因此,测试人员既是为他的各个功能设计系统测试用例的对手,也是为他的日常调试设计测试数据的助手。他还负责计划测试的步骤和为单元测试搭建测试平台。
语言专家。随着 algol语言的出现,人们开始认识到,在大多数计算机项目中,总有一两个乐于掌握复杂编程语言的人。这些专家是非常有帮助的,大家会向他咨询。这些天才不同于外科医生,外科医生主要是系统设计者以及考虑系统的整体表现。而语言专家则寻找一种简洁、有效的使用语言的方法来解决复杂、晦涩或者棘手的问题。他通常需要对技术进行一些研究(23天)。通常一个语言专家可以为23个外科医生服务。