第7章 为什么巴比伦塔会失败?
7.1 巴比伦塔项目的失败是因为缺乏交流,以及交流的结果——组织。他们无法相互交谈,从而无法合作。当合作无法进行时,工作陷入了停顿。
7.2 因为左手不知道右手在做什么,所以进度灾难、功能的不合理和系统缺陷纷纷出现。随着工作的进行,许多小组慢慢地修改自己程序的功能、规模和速度,他们明确或者隐含地更改了一些有效输入和输出结果用法上的约定。由于对其他人的各种假设,团队成员之间的理解开始出现偏差。
团队应该以尽可能多的方式进行相互之间的交流:非正式、常规项目会议,会上进行简要的技术陈述、共享的正式项目工作手册以及电子邮件。
7.3 项目工作手册:
是什么。项目工作手册不是独立的一篇文档,它是对项目必须产出的一系列文档进行组织的一种结构。项目所有的文档都必须是该结构的一部分。这包括目的、外部规格说明、接口说明、技术标准、内部说明和管理备忘录。
为什么。技术说明几乎是必不可少的。如果某人就硬件和软件的某部分,去查看一系列相关的用户手册。他发现的不仅仅是思路,而且还有能追溯到最早备忘录的许多文字和章节,这些备忘录对产品提出建议或者解释设计。对于技术作者而言,文章的剪裁粘贴与钢笔一样有用。使用项目手册的第二个原因是控制信息发布。控制信息发布并不是为了限制信息,而是确保信息能到达所有需要它的人的手中。
项目手册的第一步是对所有的备忘录编号,从而每个工作人员可以通过标题列表来检索是否有他所需要的信息。还有一种更好的组织方法,就是使用树状的索引结构。
处理机制。同许多其它的软件管理问题一样,随着项目规模的扩大,技术备忘录的问题以非线性趋势增长。工作手册的实时更新是非常关键的。工作手册的使用者应该将注意力集中在上次阅读后的变更,以及关于这些变更重要性的评述。
现在如何入手?在当今很多可以应用的技术中,我认为一种选择是采用可以直接访问的文件。在文件中,记录修订日期记录和标记变更标识条。每个用户可以从一个显示终端(打印机太慢了)来查阅。
7.4 团队组织的目的是减少不必要交流和合作的数量,因此良好的团队组织是解决上述交流问题的关键措施。
减少交流的方法是人力划分(division of labor)和限定职责范围(specialization of function)。当使用人力划分和职责限定时,树状管理结构所映出对详细交流的需要会相应减少。事实上,树状组织架构是作为权力和责任的结构出现。
树状编程队伍的每棵子树所必须具备的基本要素:
任务(a mission)
产品负责人(a producer)
技术主管和结构师(a technical director or architect)
进度(a schedule)
人力的划分(a division of labor)
各部分之间的接口定义(interface definitions among the parts)
产品负责人的角色是什么?
他组建团队,划分工作及制订进度表。他要求,并一直要求必要的资源。这意味着他主要的工作是与团队外部,向上和水平地沟通。他建立团队内部的沟通和报告方式。最后,他确保进度目标的实现,根据环境的变化调整资源和团队的构架。
技术主管的角色是什么?
他对设计进行构思,识别系统的子部分,指明从外部看上去的样子,勾画它的内部结构。他提供整个设计的一致性和概念完整性;他控制系统的复杂程度。当某个技术问题出现时,他提供问题的解决方案,或者根据需要调整系统设计。
存在三种可能的关系,它们都在实践中得到了成功的应用:
产品负责人和技术主管是同一个人。这种方式非常容易应用在很小型的队伍中,可能是三个或六个开发人员。在大型的项目中则不容易得到应用。原因有两个:第一,同时具有管理技能和技术技能的人很难找到。思考者很少,实干家更少,思考者-实干家太少了。第二,大型项目中,每个角色都必须全职工作,甚至还要加班。对负责人来说,很难在承担全部管理责任的同时,还能抽出时间进行技术工作。对技术主管来说,很难在保证设计的概念完整性,没有任何妥协的前提下,担任管理工作。
产品负责人作为总指挥,技术主管充当其左右手。这种方法有一些困难。很难在技术主管不参与任何管理工作的同时,建立在技术决策上的权威。显然,产品负责人必须预先声明技术主管的技术权威,在即将出现的绝大部分测试用例中,他必须支持后者的技术决定。要达到这一点,产品责任人和技术主管必须在基本的技术理论上具有相似观点;他们必须在主要的技术问题出现之前,私下讨论它们;产品责任人必须对技术主管的技术才能表现出尊重。
技术主管作为总指挥,产品负责人充当其左右手。我猜测最后一种安排对小型的团队是最好的选择,如同在第3章《外科手术队伍》一文中所述。对于真正大型项目中的一些开发队伍,我认为产品负责人作为管理者是更合适的安排。
第8章 胸有成竹
系统编程需要花费多长的时间?需要多少的工作量?如何进行估计?
编码大约只占了问题的六分之一左右,编码估计或者比率的错误可能会导致不合理的荒谬结果。仅仅通过对编码部分的估计,然后乘以任务其他部分的相对系数,是无法得出对整项工作的精确估计的。必须声明的是,构建独立小型程序的数据不适用于编程系统产品。
8.1 Charles Portman发现他的编程队伍落后进度大约1/2,每项工作花费的时间大约是估计的两倍。
日志显示事实上他的团队仅用了百分之五十的工作周,来进行实际的编程和调试,估算上的失误完全可以由该情况来解释。其余的时间包括机器的当机时间、高优先级的无关琐碎工作、会议、文字工作、公司业务、疾病、事假等等。简言之,项目估算对每个人年的技术工作时间数量做出了不现实的假设。
8.3 John Harr,汇报了他和其他人的经验。下图是数据最详细和最有用的。头两个任务是基本的控制程序,后两个是基本的语言翻译。生产率以经调试的指令/人年来表达。它包括了编程、构件测试和系统测试。没有包括计划、硬件机器支持、文书工作等类似活动的工作量。
生产率同样地被划分为两个类别,控制程序的生产率大约是600指令每人年,语言翻译大约是2200指令每人年。注意所有的四个程序都具有类似的规模——差异在于工作组的大小、时间的长短和模块的个数。控制程序确实更加复杂。除开这些不确定性,数据反映了实际的生产率——描述了在现在的编程技术下,大型系统开发的状况。
8.4 IBM OS/360的经验,还是证实上面那些结论。
就控制程序组的经验而言,生产率的范围大约是600~800(经过调试的指令)/人年。语言翻译小组所达到的生产率是2000~3000(经过调试的指令)/人年。这包括了小组的计划、代码构件测试、系统测试和一些支持性活动。就我的观点来说,它们同Harr的数据是可比的。
生产率会根据任务本身复杂度和困难程度表现出显著差异。在复杂程度估计这片“沼泽”上的指导原则是:编译器的复杂度是批处理程序的三倍,操作系统复杂度是编译器的三倍。
8.5 Corbato的MIT项目MAC报告表示在MULTICS系统上,平均生产率是1200行经调试的PL/I语句(大约在1和2百万指令之间)/人年。MULTICS包括了控制程序和语言翻译程序。但Corbato的数字是行/人年,不是指令!系统中的每个语句对应于手写代码的3至5个指令!
这意味着两个重要的结论:
对常用编程语句而言。生产率似乎是固定的。这个固定的生产率包括了编程中需要注释,并可能存在错误的情况;
使用适当的高级语言,编程的生产率可以提高5倍。