1.焦油坑
1.什么是焦油坑
焦油坑是作者用来形容大型系统开发的一个概念。史前时代,恐龙、猛犸象、剑齿虎这些大型食肉动物碰到焦油坑也是没有办法挣脱的,而且越用力就越容易被沉入坑底。
而在项目中好像没有任何一个单独的问题会导致困难,每个问题都能获得解决,但是当他们相互纠缠和累计在一起的时候,团队的行动就会变得越来越慢
2.编程系统产品
水平边界下,程序转变成编程产品,垂直边界下,程序变成编程系统中的构件单元,这两者的成本至少是已调试程序的成本的3倍
右下角部分代表系统编程产品,成本高达9倍,只有它才是真正有用的产品,是大多数系统开发的目标
3.职业的乐趣与苦恼
程序员是完成这一编程系统产品的重要参与人员,在整个产品开发过程中程序员能体验到很多的乐趣:创造新的功能给玩家/用户使用,面对不同任务不断学习不断进取以及可以创造出一个完全自己主宰的世界/领域。同时也会面临很多苦恼:由他人来设定目标供给资源和提供信息,BUG的排查是一件单调而痛苦的过程,最大的苦恼在于当投入大量精力在功能完成或几近完成时面临着需求变更。这就是编程,是很多人痛苦挣扎的焦油坑,也是一种乐趣与苦恼共存的创造性活动。
2.人月神话
在众多软件项目中,缺乏合理的进度安排是造成项目滞后的最主要原因,它比其他所有因素加起来的影响还要大。导致如此普遍的原因通常有:
我们过于乐观的估算了开发进度。 过于乐观的估算开发进度的背后是一个错误的假设:一切都将运行良好且每一项任务仅花费它所"应
该"花费的时间。对于一个简单的纯程序功能开发,在进度上具有可实现性,然后对于大型功能的开发,它可能包含了多个任务多个部
门,而且某些任务可能又有相互依赖关系,因此每个部门每个功能每个人都正常进展的概率变得非常小,甚至接近于零。
我们估算技术开发总是隐含的假设人和月是可以互换的,错误的将进度与工作量相互混淆。 作者认为用人月作为衡量一项工作的规模
是一个危险而带有欺骗性的神话。人数和时间的互换仅仅适用于每个人的工作相互独立且不需要交流。而在系统编程中这几乎是不可能
的,对于需要沟通的可分解任务,人员与时间的关系大致如下图
而实际上:
那么问题出在哪里呢?对进度缺少跟踪和监督
对于进度的跟踪和监督一方面是指及时掌握进度情况控制风险,另一方面是指要为功能性测试和系统测试安排足够的时间。对于一个功能的开发,作者的经验是: 1/3时间用于计划沟通,1/6时间用于编码,1/4时间用于早期功能测试,1/4时间用于系统性测试。
由于对自己的估算缺乏信心,当意识到进度存在delay风险时,下意识的反应是调配更得力的人员或者增加人力。这就像是在提油救火注定会导致灾难性的循环.前面已经提到人员数量与时间的关系,在此不再赘述。其实程序员很像是餐厅的厨师,约定两分钟后为客人提供一份煎蛋,看上去一切进行的很好,但当各种原因(鸡蛋没有了/忙着在做其他菜)它无法在两分钟内完成时,厨师的选择要么是delay,要么是加大火力提供一份半生半焦的煎蛋。此时就需要PM在更高的维度上统筹解决,例如推行生产进度图,缺陷率表,估算规则等在整体上统筹各个部门。
而这就是Brools法则:向进度落后的项目中增加人手,只会使进度更加落后。 如果一个程序10个月开发完的系统,10个人干1个月就能完成,那这就是神话。
3.外科手术队伍
面对软件项目的“焦油坑”以及“人月神话”,作者给出的一个解决办法是——“外科手术队伍”。有研究表明,同样有两年经验而且受到同样培训的情况下,优秀的专业程序员的生产率是较差程序员的10倍。在软件项目中,一个小型的、精干的队伍是最好的,这样既减少了沟通成本,又提高了生产率。
在软件项目中的“外科手术队伍”有一个类似于外科医生的首席程序员。他亲自定义功能和性能技术说明书,设计程序,编制主架构源代码,测试以及书写技术文档。首席程序员还拥有一个副手,他主要作用是作为设计的思考者、讨论者和评估人员。与传统的两人队伍每人负责一部分工作的设计和实现不同,“外科手术队伍”中的这两个人需要一起了解所有的设计和全部的代码。其他的程序员以及管理者,文档编辑人员等围绕着主架构的设计来具体实现功能以及推进项目。这种队伍的好处就在于既能获得由少数头脑产生的产品完整性,又能得到多位协助人员的总体生产率,还彻底地减少了沟通的工作量。
4.贵族专制、民族政治和系统设计
作者主张在系统设计中,概念完整性应该是最重要的考虑因素。也就是说,为了反映一系列连贯的设计思路,宁可省略一些不规则的特性和改进,也不提倡独立和无法整合的系统,哪怕它们其实包含着许多很好的设计。
对于整个项目代码结构设计应该由一个/少数几个架构师决定还是应该集思广益听取所有人意见想法后共同决定(专制/民主)?作者的答案是专制,因为系统设计的最大目标是易用性,功能与复杂程度的比值材质系统设计最终测试的标准。同一完整的概念和思路有助于降低沟通成本统一团队的思想提升开发效率。为了反映一系列连贯的设计思路,宁可省略一些不规则的特性和改进,也不提倡独立和无法整合的系统,哪怕它们其实包含着许多很好的设计。当然当其他成员提出问题/思路的共性越来越高时就应该考虑改进或者推翻现有设计思路完成设计上的迭代。
5.画蛇添足
在开发第一个系统时,架构师倾向于精炼和简洁,因为他知道自己对正在进行的任务不够了解,所以他会谨慎仔细地工作。对偶尔出现的装饰和润色功能,他通常都会选择暂时搁置一旁,作为“下一个”项目的目标。
第二个系统常常是架构师设计的最危险的系统。它常常被过度设计。在第一个系统设计完成后,架构师对这类系统充满了十足的信心,在设计第二个系统时,先前搁置的功能都被添加进来。最终导致第二个系统虽然功能齐全,但显得粗糙、浪费、不优雅,也许只有一半的功能被常规使用。
当开发第三个、第四个系统时,先前的经验会相互验证,此时的架构师将足够自律,在选择程序的功能时能够做必要的取舍。
6.贯彻执行
想要避免画蛇添足,在开发第二个系统时,架构师就应该学会这些自律。
- 文档化的规格说明------手册。作者认为仅仅有功能文档是不够,文档主要用于规定和描述用户所"看到"的内容,手册则是程序之间沟通范畴。手册的要求必须是完整清晰准确,这往往很枯燥乏味,但准确性和保证对看似琐碎问题处理原则上的一致性要比生动更加重要。(程序可以通过翻阅手册快速了解整体结构和设计思路甚至具体API接口,降低沟通成本)
- 例会。在每周例会上程序员以书面形式提出现有问题和修改意见,大家进行充分讨论达成共识。之后对进行的修改做出决策形成新的规范及文档手册。
- 电话/会议日志。无论手册写的多么详细都会出现理解不清或者误解等情况,出现这种情况后应及时电话/会议沟通,并将问题和结论形成日志合并到规范或执行手册。
- QA(质量保证工程师)。独立的QA部门将在真实环境中测试运行,使得任何缺陷都无处遁形。
7.为什么巴比伦塔会失败
巴比伦塔计划虽然有充足的人力物力财力和足够先进的技术,但由于沟通不畅,不得不走向失败的结局。它的教训告诉我们:沟通是合作的必要条件。
大型软件项目中也面临这样的情况,因为左手不知道右手在做什么,所以进度灾难、不合理的功能实现、系统缺陷纷纷出现。随着工作的不断进行,许多小组开始慢慢地修改自己程序的功能、规模和速度,当他们组合在一起时,新的程序就显得与原定目标渐行渐远。
团队之间如何有效的沟通呢?通常有三种途径:
- 电话、交谈等非正式沟通:这些途径非常方便、有效,并且随时发生在日常生活中
- 会议沟通:虽然谈到会议总是有些恼人,但会议是最正式的明确需求的途径。如果小组氛围足够和谐,会议沟通将非常有用
- 工作手册:在项目开始时,就应提纲挈领,准备好项目工作手册。指派专门的人手来维护工作手册,保证它们可以随着项目实时更新。工作手册应保持树状的索引结构,工作人员可以很方便的使用索引来检索他所需要的信息。
巴比伦塔可能是第一个失败的工程,但它不是最后一个。沟通与交流是成功的关键。这项技能需要管理者仔细考虑,相关经验的积累和能力的提高同软件技术本身一样重要。
8.胸有成竹
数据均来自当前汇编语言时代,与现在差距较大,仅供参考:
如果以先前提到的编码大约只占了开发时间的六分之一左右,用编码时间乘以六以预估开发周期其错误可能会导致不合理的荒谬结果。
9.削足适履
主要是讲程序大小的,包括代码大小和内存占用的大小。代码大小现在应该已经不是软件开发中最重要考量,但是在客户端领域可能仍然适用。
内存当然始终是一个问题,但是应该主要考虑不要发生内存泄露的问题以以及内存的合理使用等问题(仅供参考)
10.提纲掣领
思考一个问题,当我们要制作一台机器的时候,哪些是关键的文档呢? 目标(定义待满足的目标和需要,定义迫切需要的资源、约束和优先级), 技术说明(机器的性能 规格等),进度(什么时候开工,多久造出来),预算(打算花多少研发经费把它造出来),组织结构图和工作空间分配(设计到哪些部门哪些人员)。
同样的软件项目开发也需要相应的文档。那为什么需要正式文档呢?
首先,书面记录决策是必要的。只有记录下来,分歧才会明朗,矛盾才会突出。书写这项活动需要上百次的细小决定,正是由于它们的存在,人们才能从令人迷惑的现象中得到清晰、确定的策略。
项目经理常常会不断发现,许多理应被普遍认同的策略,完全不为团队的一些成员所知。每个文档本身就可以作为检查列表或者数据库。文档使各项计划和决策在整个团队范围内得到交流。通过周期性的回顾,就能清楚项目所处的状态,以及哪些需要重点进行更改和调整。
项目经理的任务是制定计划,并实现计划。但是只有书面计划是精确和可以沟通的。计划中包括了时间、地点、人员、项目内容等信息。这些少量的关键文档封装了项目经理大量的工作。如果一开始就认识到它们的普遍性和重要性,那么就可以将文档作为工具友好地利用起来,而不会让它成为令人厌烦的繁重任务。通过遵循文档开展工作,项目经理能更清晰和快速地设定自己的方向。