# 第 7 章 为什么巴比伦塔会失败?(Why Did theTower of Babel Fail?)

现在整个大地都采用一种语言,只包括为数不多的单词。在一次从东方往西方迁徙的过程中,人们发现了苏美尔地区,并在那里定居下来。接着他们奔走相告说:"来,让我们制造砖块,并把它们烧好。"于是,他们用砖块代替石头,用沥青代替灰泥(建造房屋)。然后,他们又说:"来,让我们建造一座带有高塔的城市,这个塔将高达云宵,也将让我们声名远扬,同时,有了这个城市,我们就可以聚居在这里,再也不会分散在广阔的大地上了。"于是上帝决定下来看看人们建造的城市和高塔,看了以后,他说:"他们只是一个种族,使用一种的语言,如果他们一开始就能建造城市和高塔,那以后就没有什么难得倒他们了。来,让我们下去,在他们的语言里制造些混淆,让他们相互之间不能听懂。"这样,上帝把人们分散到世界各地,于是他们不得不停止建造那座城市。(创世纪,11:1-8)

Now the whole earth used only one language, with few words. On the occasion of a migration from the east, men discovered a plain in the land of Shinar, and settled there. Then they said to one another, "Come, let us make bricks, burning them well." So they used bricks for stone, and bitumen for mortar. Then they said, "Come, let us build ourselves a city with a tower whose top shall reach the heavens (thus making a name for ourselves), so that we may not be scattered all over the earth." Then the Lord came down to look at the city and tower which human beings had built. The Lord said, "They are just one people and they all have the same language. If this is what they can do as a beginning, then nothing that they resolve to do will be impossible for them. Come, let us go down, and there make such a babble of their language that they will not understand one another's speech." Thus the Lord dispersed them from there all over the earth, so that they had to stop building the city. (Book of Genesis, 11:1-8).

# 巴比伦塔的管理教训

据《创世纪》记载,巴比伦塔是人类继诺亚方舟之后的第二大工程壮举,但巴比伦塔同时也是第一个彻底失败的工程。

这个故事在很多方面和不同层次都是非常深刻和富有教育意义的。让我们将它仅仅作为纯粹的工程项目,来看看有什么值得学习的教训。这个项目到底有多好的先决条件?他们是否有:

  1. 清晰的目标?是的,尽管幼稚得近乎不可能。而且,项目早在遇到这个基本的限制之前,就已经失败了。
  2. 人力?非常充足。
  3. 材料?在美索不达米亚有着丰富的泥土和柏油沥青。
  4. 足够的时间?没有任何时间限制的迹象。
  5. 足够的技术?是的,金字塔、锥形的结构本身就是稳定的,可以很好分散压力负载。对砖石建筑技术,人们有过深刻的研究。同样,项目远在达到技术限制之间,就已经失败了。

那么,既然他们具备了所有的这些条件,为什么项目还会失败呢?他们还缺乏些什么?两个方面——交流,以及交流的结果——组织。他们无法相互交谈,从而无法合作。当合作无法进行时,工作陷入了停顿。通过史书的字里行间,我们推测交流的缺乏导致了争辩、沮丧和群体猜忌。很快,部落开始分裂——大家选择了孤立,而不是互相争吵。

# 大型编程项目中的交流

现在,其实也是这样的情况。因为左手不知道右手在做什么,所以进度灾难、功能的不合理和系统缺陷纷纷出现。随着工作的进行,许多小组慢慢地修改自己程序的功能、规模和速度,他们明确或者隐含地更改了一些有效输入和输出结果用法上的约定。

例如,程序覆盖(program-overlay)功能的实现者遇到了问题,并且统计报告显示了应用程序很少使用该功能。基于这些考虑,他降低了覆盖功能的速度。与此同时,整个开发队伍中,其他同事正在设计监控程序。监控程序在很大程度上依赖于覆盖功能,它在速度上的变化成为了主要的规格说明变更。因此需要从系统角度来考虑和衡量该变化,以及公开、广泛地发布变更结果。

那么,团队如何进行相互之间的交流沟通呢?通过所有可能的途径。

  • 非正式途径。清晰定义小组内部的相互关系和充分利用电话,能鼓励大量的电话沟通,从而达到对所书写文档的共同理解。
  • 会议。常规项目会议。会议中,团队一个接一个地进行简要的技术陈述。这种方式非常有用,能澄清成百上千的细小误解。
  • 工作手册。在项目的开始阶段,应该准备正式的项目工作手册。理所应当,我们专门用一节来讨论它。

# 项目工作手册

是什么。项目工作手册不是独立的一篇文档,它是对项目必须产出的一系列文档进行组织的一种结构。

项目所有的文档都必须是该结构的一部分。这包括目的、外部规格说明、接口说明、技术标准、内部说明和管理备忘录。

为什么。技术说明几乎是必不可少的。如果某人就硬件和软件的某部分,去查看一系列相关的用户手册。他发现的不仅仅是思路,而且还有能追溯到最早备忘录的许多文字和章节,这些备忘录对产品提出建议或者解释设计。对于技术作者而言,文章的剪裁粘贴与钢笔一样有用。

基于上述理由,再加上"未来产品"的质量手册将诞生于"今天产品" 的备忘录,所以正确的文档结构非常重要。事先将项目工作手册设计好,能保证文档的结构本身是规范的,而不是杂乱无章的。另外,有了文档结构,后来书写的文字就可以放置在合适的章节中。

使用项目手册的第二个原因是控制信息发布。控制信息发布并不是为了限制信息,而是确保信息能到达所有需要它的人的手中。

项目手册的第一步是对所有的备忘录编号,从而每个工作人员可以通过标题列表来检索是否有他所需要的信息。还有一种更好的组织方法,就是使用树状的索引结构。而且如果需要的话,可以使用树结构中的子树来维护发布列表。

处理机制。同许多其它的软件管理问题一样,随着项目规模的扩大,技术备忘录的问题以非线性趋势增长。10 人的项目,文档仅仅通过简单的编号就可以了。100 人的项目,若干个线性索引常常可以满足要求。1000 人的项目,人员无可避免地散布在多个地点,对结构化工作手册的需要和手册规模上的要求都紧迫了许多。那么,用什么样的机制来处理呢?

我认为 OS/360 项目做得非常好。O.S.Locken 强烈要求制订结构良好的工作手册,他本人在他的前一个项目 1410-7010 操作系统中,看到了工作手册的效果。

我们很快决定了每一个编程人员应该了解所有的材料,即在每间办公室中应保留一份工作手册的拷贝。

工作手册的实时更新是非常关键的。工作手册必须是最新的,如果每次变更都要重新打印所有的文档,实际上这很难做到。不过,如果采用活页夹的方式,则仅需更换变更页。我们当时拥有计算机编辑系统,它对实时维护有不可思议的帮助。编辑、排版、打印的工作直接在计算机和打印机上完成,周转时间少于一天。但即便如此,所有接收的人员还是会面临消化理解的问题。当他第一次收到更改页时,他需要知道,"修改了什么?"迟些时候,当他就问题进行咨询时,他需要知道,"现在的定义是什么?"。

理解的问题可以通过持续的文档维护来解决。文档变更的强调有若干个步骤。首先,必须在页面上标记发生改变的文本,例如,使用页边上的竖线标记每行变化的文字。第二,分发的变更页附带独立的总结性文字,对变更的重要性以及批注进行记录。

这种机制在我们项目中碰到别的问题之前,稳定运行了六个月。工作手册大约厚达 1.5 米!如果将我们在曼哈顿 Time-Life 大厦办公室里所使用的 100 份手册叠在一起,它们比这座大厦还要高。另外,每天分发的变更页大约 5 厘米,归入档案的页数大概有 150 页。日常工作手册的维护工作占据了每个工作日的大量时间。

这个时候,我们换用了微缩胶片,在为每个办公室配备了微缩胶片阅读机之后,节约了大量金钱,工作手册的体积减少了 18 倍。更重要的是,对数百页更新工作的帮助——微缩胶片大量地减轻了归档问题。

微缩胶片有它的缺点。从管理的角度而言,笨拙的文字归档工作确保了所有变更会被阅读,这正是工作手册要达到的目的。微缩胶片使工作手册的维护工作变得过于简单,除非列举变化的文字说明和变更胶片一起分发。

另外,微缩胶片不容易被读者强调、标记和批注。对作者来说,采用文档方式与读者沟通更加有效;对读者来说,文档更加容易使用。

总之,我觉得微缩胶片是非常好的一种方法。对于大型项目,我建议把它作为文字工作手册的补充。

现在如何入手?在当今很多可以应用的技术中,我认为一种选择是采用可以直接访问的文件。在文件中,记录修订日期记录和标记变更标识条。每个用户可以从一个显示终端(打印机太慢了)来查阅。每日维护的变更小结以"后进先出"的方式保存,在一个固定的地方提供访问。编程人员可能会每天阅读,但如果错过了一天,他只需在第二天多花一些时间。在他查看小结的同时,他可以停下来,去查询变更的文字。

注意工作手册本身没有发生变化。它还是所有项目文档的集合,根据某种经过细致考虑的规则组织在一起。唯一发生改变的地方是分发机制和查询方法。斯坦福研究机构的 D.C.Engelbart 和同事开发了一套系统,并用它在 ARPA 网络项目中建立和维护文档。

卡内基-梅隆大学的 D.L.Parnas 提出了更彻底的解决方法 1。他认为,编程人员仅了解自己负责的部分,而不是整个系统的开发细节时,工作效率最高。这种方法的先决条件是精确和完整地定义所有接口。这的确是一个彻底的解决方法。如果能处理得好,的确是能解决很多"灾难"。一个好的信息系统不但能暴露接口错误,还能有助于改正错误。

# 大型编程项目的组织架构

如果项目有 n 个工作人员,则有(n2 - n)/ 2 个相互交流的接口,有将近 2n 个必须合作的潜在团队。团队组织的目的是减少不必要交流和合作的数量,因此良好的团队组织是解决上述交流问题的关键措施。

减少交流的方法是人力划分(division of labor)和限定职责范围(specialization of function)。当使用人力划分和职责限定时,树状管理结构所映出对详细交流的需要会相应减少。

事实上,树状组织架构是作为权力和责任的结构出现。其基本原理——管理角色的非重复性——导致了管理结构是树状的。但是交流的结构并未限制得如此严格,树状结构几乎不能用来描述交流沟通,因为交流是通过网状结构进行的。在很多工程活动领域,树状模拟结构不能很精确地用于描述一般团队、特别工作组、委员会,甚至是矩阵结构组织。

让我们考虑一下树状编程队伍,以及要使它行之有效,每棵子树所必须具备的基本要素。它们是:

  1. 任务(a mission)
  2. 产品负责人(a producer)
  3. 技术主管和结构师(a technical director or architect)
  4. 进度(a schedule)
  5. 人力的划分(a division of labor)
  6. 各部分之间的接口定义(interface definitions among the parts)

所有这些是非常明显和约定俗成的,除了产品负责人和技术主管之间有一些区别。我们先分析一下两个角色,然后再考虑它们之间的关系。

产品负责人的角色是什么?他组建团队,划分工作及制订进度表。他要求,并一直要求必要的资源。这意味着他主要的工作是与团队外部,向上和水平地沟通。他建立团队内部的沟通和报告方式。最后,他确保进度目标的实现,根据环境的变化调整资源和团队的构架。

那么技术主管的角色是什么?他对设计进行构思,识别系统的子部分,指明从外部看上去的样子,勾画它的内部结构。他提供整个设计的一致性和概念完整性;他控制系统的复杂程度。当某个技术问题出现时,他提供问题的解决方案,或者根据需要调整系统设计。用 Al Capp 所喜欢的一句谚语,他是"攻坚小组中的独行侠"(inside-man at the skunk works.)。他的沟通交流在团队中是首要的。他的工作几乎完全是技术性的。

现在可以看到,这两种角色所需要的技能是非常不同的。这些技能可以按不同的方式进行组合。产品负责人和技术主管所拥有的特殊技能可以用不同方式组合,组合结果控制和支配了他们之间的关系。团队的搭建必须根据参与的人员来组织,而不是将人员纯粹地按照理论进行安排。

存在三种可能的关系,它们都在实践中得到了成功的应用。

产品负责人和技术主管是同一个人。这种方式非常容易应用在很小型的队伍中,可能是三个或六个开发人员。在大型的项目中则不容易得到应用。原因有两个:第一,同时具有管理技能和技术技能的人很难找到。思考者很少,实干家更少,思考者——实干家太少了。

第二,大型项目中,每个角色都必须全职工作,甚至还要加班。对负责人来说,很难在承担全部管理责任的同时,还能抽出时间进行技术工作。对技术主管来说,很难在保证设计的概念完整性,没有任何妥协的前提下,担任管理工作。

产品负责人作为总指挥,技术主管充当其左右手。这种方法有一些困难。很难在技术主管不参与任何管理工作的同时,建立在技术决策上的权威。

显然,产品负责人必须预先声明技术主管的技术权威,在即将出现的绝大部分测试用例中,他必须支持后者的技术决定。要达到这一点,产品责任人和技术主管必须在基本的技术理论上具有相似观点;他们必须在主要的技术问题出现之前,私下讨论它们;产品责任人必须对技术主管的技术才能表现出尊重。

另外,还有一些技巧。例如,产品责任人可以通过一些微妙状态特征暗示来(如,办公室的大小、地毯、装修、复印机等等)体现技术主管的威信,尽管决策权力的源泉来自管理。

这种组合可以使工作很有效。不幸的是它很少被应用。不过,它至少有一个好处,即项目经理可以使用并不很擅长管理的技术天才来完成工作。

技术主管作为总指挥,产品负责人充当其左右手。Robert Heinlein 在《出售月球的人》("The Man Who Sold the Moon")中,用一幅场景描述了这样的安排:

Coster 低下头,双手捂着脸,接着,抬起头。"我知道。我了解需要做什么——但每次我试图解决技术问题时,总有些该死的笨蛋要我做一些关于卡车、或者电话、以及其他一些讨厌的事情。我很抱歉。Harriman 先生,我原以为我可以处理好。"

Harriman 非常温和的说:"Bob,别让这些事烦你。近来好像睡眠不大好,是吗?告诉你吧。我将在你的位子上干几天,为你搭建一个免于这些事情干扰的环境。我需要你的大脑

工作在反向量、燃油效率和压力设计上,而不是卡车的合同。"Harriman 走到门边,扫了一圈,点了一个可能是、也可能不是办公室主要职员的工作人员。"嘿,你!过来一下。"

那个人看上去有些惊慌,站了起来,走到门边说道,"什么事?"

"把角落上的那个桌子和上面所有的东西搬到本层楼的一个空的办公室去,马上。"

他监督着 Coster 和他的桌子移到另一个办公室,看了看,发现新办公室的电话没有接上。接着,想了一下,搬了一个长沙发过来。"今晚我们将安装一个投影仪、绘图仪、书架和其他一些东西,"他告诉 Coster。"把你工程所需要的东西列一个表。"他回到了原来的总工程师办公室,愉快地想了想如何进行工作组织,以及是否有什么不妥。

过了四个小时,他带 Berkeley 进来,与 Coster 会面。这位总工程师正在他的桌子上睡觉,头枕在臂弯里。Harriman 慢慢地退出去,但 Coster 醒了过来。"喔,对不起,"他有点不好意思地说,"我肯定是打了个瞌睡。"

"这就是我给你带来长沙发的原因,"Harriman 说道。"它更加舒适。Bob,来见一下 Jock Berkeley。他是你的新奴隶,你仍是总工程师,毫无疑问的老板。Jock 是其他一切的主管。从现在起,你不需要担心其他的任何问题,除了建造登月飞船的一些细节问题。"

他们握了一下手。"Coster 先生,我只想问一件事,"Berkeley 认真的说,"所有你需要做的事,我都无权过问——你即将进行一个技术演示——但是看在上帝的份上,能否记录一下,从而让我了解一下。我将会把一个开关放在你的桌上,它会开启桌上的一个密封的录像机。"

"好的!"Coster 正看着他,Harriman 想,够年轻的。

"如果要做任何非技术的事情,不需要自己动手。只需按个按钮知会一声,它们就会被完成!"Berkeley 扫了 Harriman 一眼。"老板说他想同你谈一谈实际的工作。我得先走,去忙去了。"他离开了。

Harriman 坐了下来,Coster 整了整衣服,说道,"喔!"

"感觉好一些了?"

"我喜欢 Berkeley 这小伙子的样子。"

"太好了!不用担心,他现在就是你的孪生兄弟。我以前用过他。你可以认为你正住在一个头等的疗养院里。"

这个故事几乎不需要任何的分析解释,这种安排同样能使工作非常有效。

我猜测最后一种安排对小型的团队是最好的选择,如同在第 3 章《外科手术队伍》一文中所述。对于真正大型项目中的一些开发队伍,我认为产品负责人作为管理者是更合适的安排。

巴比伦塔可能是第一个工程上的彻底失败,但它不是最后一个。交流和交流的结果——组织,是成功的关键。交流和组织的技能需要管理者仔细考虑,相关经验的积累和能力的提高同软件技术本身一样重要。