# 第 6 章 贯彻执行(Passing the Word)
他只是坐在那里,嘴里说:"做这个!做那个!"当然,什么都不会发生,光说不做是没有用的。
——哈里·杜鲁门,关于总统的权力
He'll sit here and he'll say, "Do this! Do that!" And nothing will happen.
——HARRY S. TRUMAN, ON PRESIDENTIAL POWER
假设一个项目经理已经拥有行事规范的结构师和许多编程实现人员,那么他如何确保每个人听从、理解并实现结构师的决策?对于一个由 1000 人开发的系统,一个 10 个结构师的小组如何保持系统概念上的完整性?在 System/360 硬件设计工作中,我们摸索出来一套实现上述目标的方法,它们对于软件项目同样适用。
# 文档化的规格说——手册
手册、或者书面规格说明,是一个非常必要的工具,尽管光有文档是不够的。手册是产品的外部规格说明,它描述和规定了用户所见的每一个细节;同样的,它也是结构师主要的工作产物。
随着用户和实现人员反馈的增加,规格说明中难以使用和难以构建实现的地方不断被指出,规格说明也不断地被重复准备和修改。然而对实现人员而言,修改的阶段化是很重要的——在进度表上应该有带日期的版本信息。
手册不但要描述包括所有界面在内的用户可见的一切,它同时还要避免描述用户看不见的事物。后者是编程实现人员的工作范畴,而实现人员的设计和创造是不应该被限制的。体系结构设计人员必须为自己描述的任何特性准备一种实现方法,但是他不应该试图支配具体的实现过程。
规格说明的风格必须清晰、完整和准确。用户常常会单独提到某个定义,所以每条说明都必须重复所有的基本要素,所以所有文字都要相互一致。这往往使手册读起来枯燥乏味,但是精确比生动更加重要。
System/360 Principles of Operation 的一致完整性来自仅有两名作者的事实:Gerry Blaauw 和 Andris Padegs。思路是大约十个人的想法,但如果想保持文字和产品之间的一致性,则必须由一个或两个人来完成将其结论转换成书面规格说明的工作。而且,将定义书写成文字,必须对很多原先并不是非常重要的问题进行判断,并得出结论。例如,System/360 需要决定在每次操作后,如何设置返回的条件码。其实,对于在整个设计中,保证这些看似琐碎的问题处理原则上的一致性,决不是一件无关紧要的事情。
我想我所见过的最好的一份手册是 System360 Principles of Operation 的附录。它精确仔细地规定了 System/360 兼容性的限制。它定义了兼容性,描述了将达到的目标,列举了很多外部显示的各个部分:源于某个模型与其他模型差异,带来变化的部分和保持不变的部分;或者是某个给定模型的拷贝不同于其他拷贝的地方;甚至是工程上的变更引起拷贝自身上的差异。而这正是一个规格说明作者所应该追求的精确程度,他必须在仔细定义规定什么的同时,定义未规定什么。
# 形式化定义
英语或者其他任何的人类语言,从根本上说,都不是一种能精确表达上述定义的手段。因此,手册的作者必须注意自己的思路和语言,达到所需要的精确程度。一种颇具吸引力的作法是对上述定义使用形式化标记方法。毕竟,精确度是我们需要的东西,这也正是形式化标记方法存在的理由和原因。
让我们来看一看形式化定义的优点和缺点。如文中所示,形式化定义是精确的,它们倾向于更加完整;差异得更加明显,可以更快地完成。但是形式化定义的缺点是不易理解。记叙性文字则可以显示结构性的原则,描述阶段上或层次上的结构,以及提供例子。它可以很容易地表达异常和强调对比的关系,最重要的是,它可以解释原因。在表达的精确和简明性上,目前所提出的形式化定义,具有了令人惊异的效果,增强了我们进行准确表达的信心。但是,它还需要记叙性文字的辅助,才能使内容易于领会和讲授。出于这些原因,我想将来的规格说明同时包括形式化和记叙性定义两种方式。
一句古老的格言警告说:"决不要携带两个时钟出海,带一个或三个。"同样的原则也适用于形式化和记叙性定义。如果同时具有两种方式,则必须以一种作为标准,另一种作为辅助描述,并照此明确地进行划分。它们都可以作为表达的标准,例如,Algol 68 采用形式化定义作为标准,记叙性文字作为辅助。PL/I 使用记叙性定义作为主要方式,形式化定义用作辅助表述。System/360 也将记叙性文字用作标准,以及形式化定义用作派生的论述。
很多工具可以用于形式化定义,例如巴科斯范式在语言定义中很常用,它在书本中有详细的描述。PL/I 的形式化定义使用了抽象语法的新概念,该概念有很确切的解释。Iverson 的 APL 曾用来描述机器,突出的应用是 IBM 7090 和 System/360。
Bell 和 Newell 建议了能同时描述配置和机器结构的新标注方法,并且在许多机型的应用上得以体现,如 DEC PDP-86、70908、System/360。
在规定系统外部功能的同时,几乎所有的形式化定义均会用来描述和表达硬件系统或软件系统的某个设计实现。语法和规则的表达可以不需要具体的设计实现,但是特定的语义和意义通常会通过一段实现该功能的程序来定义。理所当然,这是一种实现,不过它过多地限定了体系结构。所以必须特别指出形式化定义仅仅用于外部功能,说明它们是什么。
如同前面所示,形式化定义可以是一种设计实现。反之,设计实现也可以作为一种形式化定义的方法。当制造第一批兼容性的计算机时,我们使用的正是上述技术:新的机器同原有的机器一致。如果手册有一些模糊的地方?"问一问机器!"——设计一段程序来得到其行为,新机器必须按照上述结果运行。
硬件或软件系统的仿真装置,可以按照相同的方式完整运用。它是一种实现,可以运行。因此,所有定义的问题可以通过测试来解决。
使用实现来作为一种定义的方式有一些优点。首先,所有问题可以通过试验清晰地得到答案,从来不需要争辩和商讨,回答是快捷迅速的。通过定义得出的答案,总是同所要求的一样精确和正确。但是,相对于这些优点的,是一系列可怕的缺点。实现可能更加过度地规定了外部功能。例如,无效的语法通常会产生某些结果。在拥有错误控制的系统中,它通常仅仅导致某种"无效"的指示,而不会产生其他的东西。在无错误控制的系统中,会产生各种副作用,它们可能被程序员所使用。例如,当我们着手在 System/360 上模拟 IBM 1401 时,有 30 个不同的"古玩"——被认为是无效操作的副作用——得到广泛的应用,并被认为是定义的一部分。作为一种定义,实现体现了过多的内容:它不但描述了系统必须做什么,同时还声明了自己到底做了些什么。
因此,当尖锐的问题被提及时,实现有时会给出未在计划中的意外答案;这些答案中,真正的定义常常是粗糙的,因为它们从来没有被仔细考虑过。这些粗糙的功能在其他的设计实现中,往往是低效或者代价高昂的。例如,一些机器在乘法运算之后,将某些运算的垃圾遗留在被乘数寄存器中。该功能确切的特性,即保存运算垃圾,成为了真正定义的一部分。然而,重复该细节可能会阻止某些快速乘法算法的使用。
最后,关于实际使用标准是形式化描述还是叙述性文字这一点而言,使用实现作为形式化定义特别容易引起混淆,特别是在程序化的仿真中。另外,当实现充当标准时,还必须防止对实现的任何修改。
# 直接整合
对软件系统的体系结构师而言,存在一种更加可爱的方法来分发和强制定义。对于建立模块间接口语法,而非语义时,它特别有用。这项技术是设计被传递参数和共享存储器的声明,并要求编程实现在编译时的一些操作(PL/I 的宏或%INCLUDE)来包含这些声明。另外,如果整个接口仅仅通过符号名称进行引用,那么需要修改声明的时候,可以通过增加或插入新变量,或者重新编译受影响的程序。这种方法不需要修改程序内容。
# 会议和大会
无需多说,会议是必要的。然而,数百人在场的大型磋商会议往往需要大规模和非常正式地召集。因此,我们把会议分成两个级别:周例会和年度大会——这实际上是一种非常有效的方式。
周例会是每周半天的会议,由所有的结构师,加上硬件和软件实现人员代表和市场计划人员参与,由首席系统结构师主持。
会议中,任何人可以提出问题和修改意见,但是建议书通常是以书面形式,在会议之前分发。新问题通常会被讨论一些时间。重点是创新,而不仅仅是结论。该小组试图发现解决问题的新方法,然后少数解决方案会被传递给一个和几个结构师,详细地记录到书面的变更建议说明书中。
接着会对详细的变更建议做出决策。这会经历几个反复过程,实现人员和用户会仔细地进行考虑,正面和负面的意见都会被很好地描述。如果达成了共识,非常好;如果没有,则由首席结构师来决定。这需要花费时间,最终所发布的结论是正式和果断的。
周例会的决策会给出迅捷的结论,允许工作继续进行。如果任何人对结果过于不高兴,可以立刻诉诸于项目经理,但是这种情况非常少见。
这种会议的卓有成效是由于:
- 数月内,相同小组——结构师、用户和实现人员——每周交流一次。因此,大家对项目相关的内容比较了解,不需要安排额外时间对人员进行培训。
- 上述小组十分睿智和敏锐,深刻理解所面对的问题,并且与产品密切相关。没有人是"顾问"的角色,每个人都要承担义务。
- 当问题出现时,在界线的内部和外部同时寻求解决方案。
- 正式的书面建议集中了注意力,强制了决策的制订,避免了会议草稿纪要方式的不一致。
- 清晰地授予首席结构师决策的权力,避免了妥协和拖延。
随着时间的推移,一些决定没有很好地贯彻,一些小事情并没有被某个参与者真正地接受,其他决定造成了未曾遇到的问题。对于这些问题,有时周例会没有重新考虑,慢慢地,很多小要求、公开问题或者不愉快会堆积起来。为解决这些堆积起来的问题,我们会举行年度大会,典型的年度大会会持续两周。(如果由我重新安排,我会每六个月举行一次。)
这些会议在手册冻结的前夕召开。出席人员不仅仅包括体系结构小组和编程人员、实现人员的结构代表,同时包括编程经理、市场和实现人员,由 System/360 的项目经理主持。议程典型地包括大约 200 个条目,大多数条目的规模很小,它们列举在会议室周围的图表上,每个不同的声音都有机会得到表达。然后,会制订出决策,加上出色的计算机化文本编辑工作(许多优秀员工的卓越的工作成果)。每天早晨,会议参与人员会在座位上发现更新了的手册说明,记录了前一天的各项决定。
这些"收获的节日"不仅可以解决决策上的问题,而且使决策更容易被接受。每个人都在倾听,每个人都在参与,每个人对复杂约束和决策之间的相互关系有了更透彻的理解。
# 多重实现
System/360 的结构师具有两个空前有利的条件:充足的工作时间,拥有与实现人员相同的策略影响力。充足时间来自新技术的开发日程;而多重实现的同时开发带来了策略上的平等性。不同实现之间严格要求相互兼容,这种必要性是强制规格说明的最佳代言人。
在大多数计算机项目中,机器和手册之间往往会在某一天出现不一致,人们通常会忽略手册。因为与机器相比,手册更容易改动,并且成本更低。然而,当存在多重实现时,情况就不是这样。这时,如实地遵从手册更新机器所造成的延迟和成本的消耗,比根据机器调整手册要低。
在定义某编程语言的时候,上述概念可以卓有成效地得到应用。可以肯定的是,迟早会有很多编译器或解释器被推出,以满足各种各样的目标。如果起初至少有两种以上的实现,那么定义会更加整洁和规范。
# 电话日志
随着实现的推进,无论规格说明已经多么精确,还是会出现无数结构理解和解释方面的问题。显然有很多问题需要文字澄清和解释,还有一些仅仅是因为理解不当。
显然,对于存有疑问的实现人员,应鼓励他们打电话询问相应的结构师,而不是一边自行猜测一边工作,这是一项很基本的措施。他们还需要认识到的是,上述问题的答案必须是可以告知每个人的权威性结论。
一种有用的机制是由结构师保存电话日志。日志中,他记录了每一个问题和相应的回答。每周,对若干结构师的日志进行合并,重新整理,并发布给用户和实现人员。这种机制很不正式,但非常快捷和易于理解。
# 产品测试
项目经理最好的朋友就是他每天要面对的敌人——独立的产品测试机构/小组。该小组根据规格说明检查机器和程序,充当麻烦的代言人,查明每一个可能的缺陷和相互矛盾的地方。每个开发机构都需要这样一个独立的技术监督部门,来保证其公正性。
在最后的分析中,用户是独立的监督人员。在残酷的现实使用环境中,每个细微缺陷都将无从遁形。产品——测试小组则是顾客的代理人,专门寻找缺陷。不时地,细心的产品测试人员总会发现一些没有贯彻执行、设计决策没有正确理解或准确实现的地方。出于这方面的原因,设立测试小组是使设计决策得以贯彻执行的必要手段,同样也是需要尽早着手,与设计同时实施的重要环节。