第五章画足添蛇(THE SECOND-SYSTEM EFFECT)
架构设计师面对过高的估算的两个选择:
- 削减设计
- 向开发人员建议用成本更低的实现方法
第2个选择若要成功,架构设计师必须:
- 记住开发人员有发会创意完成实作的任务,所以架构设计师只能建议。
- 在建议时,提出一个能够符合规格的实现方法,同时也接受其他能够达到目标的方桉。
- 默默地,私底下提出建议。
- 准备放弃所作的改进建议。
这边所谓的「第二系统效应」,是指一个人在设计系统的时候,第二个设计出来的系统,是最危险的一个。这是因为在第一个系统的时候,由于自知不够熟系,所以会比较节制、也会比较简单清爽;
但是设计第二个系统的时候,却很容易把在做第一个系统时的所有构想,都加挂到这个自认已经熟系的第二个系统上,所以第二个系统很容易有过度设计的问题。再之后的系统(第三个及以后),由于会和之前的经验做对比、相互印证,所以也就比较不会有问题了~
如何避免这个问题?
以设计师来说:
- 主要就是要靠「自律」了~同时,也要了解这个第二系统效应的原因,并提醒自己避免设计出不相关的功能、或是做出违反原先架设与目的的功能。
- 为每个小功能分配一个值:每次改进,功能x不超过m子节的内存和n微秒
项目经理来说:
- 要采用至少两个以上系统设计经验的架构设计老手的决定。
- 保持对特殊诱惑的警觉。
第六章贯彻执行(PASSING THE WORD)
这一章主要的主题,是着重于整个意思的传达,以及精确的描述;因为唯有在所有参与专桉的人都能够明确无误地了解整个架构、规范、介面等等必须要沟通的东西时,才有可能真正完全按照计画来进行。而针对了这个主题,作者也在本章内提出了许多建议:
书面规则/手册
- 不仅要描述使用者将会看到的所有细节,也要避免描述使用者看不到的东西。
- 手册的风格应该要准确、完整、详细,各项定义与要点必须要保持一致;而为了做到这点,所以书面化的工作应该要由一到两个个人来主笔。
形式化定义
- 采用「形式化标记法」(formal notation)。
- 为了精确,使用「形式化定义」(formal definition),
- 为了易懂,也需要「记述性定义」(prose definition);
- 而这两者之中,要有一个是主要标准,另一个则辅助描述。
-设计实现也可以当作正式定义,例如用模拟器来当作定义。
- 这样的好处是只要实际测试一下,就知道他应该有什么结果;
- 但是相对的,也有可能因此会因为这个实现,而导致定义的过度描述,而影响到之后实现的弹性。
开会
1周例会
- 由首席系统架构设计师担任主席、时间较短(半天)
- 任何与会人员都可以提出问题和修改意见(但是要先提交书面资料),重点在于激发创意;
- 而在提桉后由架构设计师整理成为较精细的提桉报告。
- 会议决策权在首席系统架构设计师上,最后的结果要正式、即时、全面地公告。如此可以使各项决策迅速敲定、让工作得以顺利进行。
2年度大会
- 时间较长(两周)
- 用来处理细琐事务、公开讨论,让大家发洩不满。
多重实现
一开始就开发两个以上的实现产品,可以避免根据错误的实现去修改规格,将有助于维持架构定义的纯净与严谨。
电话日志
- 允许实现人员直接询问架构设计师(电话、或者电子邮件),而不要自行解释。
- 而这些询问都应该被记录下来、整理后分发给所有实现人员和使用者。
产品测试
独立的产品测试小组是必须的。
第七章为什么巴比伦塔会失败?(WHY DID THE TOWER OF BABEL FAIL?)
巴别塔失败的原因是什麽?作者认为是「沟通」,以及随之而来的「组织」;
怎样沟通?
- 非正式的方法(电话、电子邮件)
- 会议
- 工作手册 是一份对项目必须产出的一系列文件的组织结构,包括目的,外部规格说明,接口说明,技术标准,内部说明和管理备忘录。
使用工作手册的原因?
- 规范了专桉进行过程中即将产生的文件,并可以用来保存技术方面的说明;而为了让工作手册可以真正有用,他需要被尽早、小心地设计出来。
- 控制信息发布:确保需要资讯的人都能够在适当的地方取得资讯的方法,每一个团队的成员都应该要可以看到工作手册的全部文件内容(没有必要所有人都要看完所有的东西,部分的细节应该要被封装(encapsulated)起来,不属于自己的东西,就不必、也不被允许去看裡面的细节,只需要看到简介就够了。)(对备忘录编号,建立树状索引结构);同时也要确保文件的内容有被持续地更新,并且保有改版的纪录,让看的人知道版本间的修改状况。在以往这点可能很难做到,但是现在网路、电子化文件都很发达了,要做到基本上问题并不大。
大型编程项目的组织架构
「组织」的目的:减少沟通量。
- 人力配置
- 专业分工
传统的树状结构组织主要是源自于权力的责任结构,但是以沟通结构来说,则是会是网状的,这样才可以避免沟通不良的问题。
树状编程队伍:
- 任务(a mission)
- 产品负责人(a producer)
- 技术主管或结构师(a technical director or architect)
- 进度(a schedule)
- 人力划分(a division of labor)
2负责着急小组、分派工作、规划时程、争取掌握资源,以及和别的小组沟通,并且对时程负责;
3则是构思、分割系统,切割系统的外观和内构,维持整个设计的和谐与整体性。
作者认为,这两种脚色的搭配方法有三种:
- 管理者兼任技术总监 主要适合于小型团队,不是用于大型团队。
- 管理者是总指挥、技术总监是副手
- 技术总监是总指挥、管理者是副手
第八章胸有成竹(CALLING THE SHOT)
本章的是在讨论要如何预估一个项目所需的时间;
写一个独立小程式所花的时间,不能拿来做为预估整个软体系统产品开发时程之用;规划、写文件、测试、系统整合以及训练的时间,都是必须加以考量的,线性外推种天真的做法是没有意义的。
即使只考虑个人创作,不含任何和别人沟通的代价
工作量=常数× 指令的数量 1.5
Charles Portman
在国际电脑的经验是,在上班时间大概只有 50% 的时间是真正在写程式或除错,其他的杂物会佔去大概一半的时间。
Joel Aron
在 IBM 的经验,在一个大型系统(25 个程式设计师、30,000 行程式)的子系统
- 非常少的交互 10,000 个指令每人年;
- 少量的交互 5000 个指令每人年;
- 较多的交互 1200 个指令每人年;
John Harr
在贝尔实验室以及 Brooks 自己在 IBM 的经验,作业系统/控制程式这类的程式生产力大约是每人年 600 – 800 个指令,编译器这类的程式则大约是每人年 2,000 – 3,000 个指令。(这两者都是组合语言)
Corbató
在麻省理工 Multics 专桉的数据显示,使用 PL/I(某古老的高阶程式语言、维基百科)开发介于作业系统和编译器之间的溷和程式,其生产力大约是每人年 1,200 行程式(每行约可抵三到五个字)。
生产率会根据复杂度和困难度表现差异:
编译器复杂度=批处理程序× 3
操作系统复杂度=编译器× 3
结论是:
- 生产力若以编程语句来算,似乎是个固定值(包括注释,并可能存在错误);
- 如果采用了合适的高阶语言,软体开发的生产力也许可以提高五倍。