02.11 这就是所谓的软工圣经?

人月神话

IBM System/360系統之父 佛瑞德·布魯克斯(Frederick Phillips Brooks, Jr) 所著經典文集。 软体工程的神品。40周年中文纪年版。

全球最大的软件消费者(美国军方)每年买数十亿美元购买软件,其购买直接使用的只有 2%,另外 3%需要一些修改,其他 95% 垃圾。他们显然没有很满足客户的需求。

完整程序

水平边界以下,程序变成编程产品(Programming Product)。 这是可以被任何人运行、测试、修复和扩展的程序。它可以运行在多种操作系统平台上,供多套数据使用。要成为通用的编程品。

垂直边界的右边,程序变成编程系统(Programming System)中的一个构件单元。它是在功能上能相互协作的程序集合,具有规范的格式,可以进行交互,并可以用来组装和搭建整个系统。

当要做一个完整的程序需要 3 * 3 = 9 工作量。

3*3工作量

人月神话

当意识到进度的偏移时,下意识(以及传统)的反应是增加人力。这就像使用汽油灭火一样,只会使事情更糟。解释如下:

人数和时间的互换仅仅适用于以下情况:某个任务可以分解给参与人员,并且他们之间『 不需要相互的交流 』。

人数与时间

当任务由于次序上的限制不能分解时,人手的添加对进度没有帮助。

任务次数受限时,人与时间

一对一交流的情况下,三个人的工作量是两个人的三倍,四个人则是两个人的六倍。

以两个人的工作量以此类推,则工作量按照n(n-1)/2递增。(我觉得单纯他只是评估沟通的成本)

不论在多短的时间内,聘请到多么能干的两位新员工,他们都需要接受一位有经验的职员的培训。如果培训需要一个月的时间,那么三个人月将会投入到原有进度安排以外的工作中

添加新员工

添加更多人力,结果往往会是上述循环的重复。这简直就是一种疯狂、愚蠢的做法。

开发时间规划如下:

1/3计划

1/6编码

1/4构件测试和早期系统测试

1/4系统测试,所有的构件已完成

二次成本远远高于其他开销。因此,在早期进度策划时,允许充分的系统测试时间是非常重要的。

人员的数量依赖于单个子任务的数量。分派较多的人手,计划较短的时间,将无法得到可行的进度表。 自己解读:所以尽量将工作独立细分,减少沟通时间。

外科手术

在该小组中,最好的和最差的表现在生产率上平均为10:1;在运行速度和空间上具有5:1的惊人差异!

简言之,$20,000/年的程序员的生产率可能是$10,000/年程序员的10倍。

成本的主要组成部分是相互的沟通和交流,以及更正沟通不当所引起的不良结果(系统调试)。

外科医生

外科医生。Mills称之为首席程序员。他亲自定义功能和性能技术说明书,设计程序,编制源代码,测试以及书写技术文档

副手。他是外科医生的后备,能完成任何一部分工作,但是相对具有较少的经验。他的主要作用是作为设计的思考者、讨论者和评估人员

管理员。外科医生是老板,他必须在人员、加薪等方面具有决定权

编辑。外科医生负责产生文档——出于最大清晰度的考虑,他必须书写文档

两个秘书。管理员和编辑每个人需要一个秘书

程序职员。他负责维护编程产品库中所有团队的技术记录。

工具维护人员。现在已经有很多文件编辑、文本编辑和交互式调试等工具,因此团队很少再需要自己的机器和机器操作人员

测试人员。外科医生需要大量合适的测试用例,用来对他所编写的工作片段,以及对整个工作进行测试

语言专家。随着Algol语言的出现,人们开始认识到大多数计算机项目中,总有一两个乐于掌握复杂编程语言的人。这些专家非常有帮助,很快大家会向他咨询。这些天才不同于外科医生,外科医生主要是系统设计者以及考虑系统的整体表现。而语言专家则寻找一种简洁、有效的使用语言的方法来解决复杂、晦涩或者棘手的问题。

观点的不一致由外科医生单方面来统一

系统设计

概念的完整性要求设计必须由一个人。

系统的结构师,如同建筑的结构师一样,是用户的代理人。结构师的工作,是运用专业技术知识来支持用户的真正利益

如果出现了很多非常重要但不兼容的构想,就应该抛弃原来的设计,对不同基本概念进行合并,在合并后的系统上重新开始。

体系结构(architecture)、设计实现(implementation)、物理实现(realization)

架构师的交互准则与机制

结构师有两个选择:削减设计或者建议成本更低的实现方法。

牢记是开发人员承担创造性和发明性的实现责任,所以结构师只能建议,而不能支配;

时刻准备着为所指定的说明建议一种实现的方法,同样准备接受其他任何能达到目标的方法;

对上述的建议保持低调和平静;

准备放弃坚持所作的改进建议。

开发第二个系统所引起的后果纯粹的功能修饰和增强明显不同,也就是说存在对某些技术进行细化、精炼的趋势。由于基本系统设想发生了变化,这些技术已经显得落后。(自己解读:担心故步自封,不追求进步)

一个可以开阔结构师眼界的准则是为每个小功能分配一个值:每次改进,功能x不超过m字节的内存和n微秒

总结:以上也就是说,当制作第二个系统,需要因应技术的演进,适当的做优化、以求系统的进步。

会议

周例会是每周半天的会议,由所有的结构师,加上硬件和软件实现人员代表和市场计划人员参与,由首席系统结构师主持。

如果达成了共识,非常好;如果没有,则由首席结构师来决定

每周交流一次。因此,大家对项目相关的内容比较了解,不需要安排额外时间对人员进行培训。

清晰地授予首席结构师决策的权力,避免了妥协和拖延。

我们会举行年度大会,典型的年度大会会持续两周。(如果由我重新安排,我会每六个月举行一次。)

开发进行中

对于存有疑问的实现人员,应鼓励他们打电话询问相应的结构师,而不是一边自行猜测一边工作,这是一项很基本的措施

多交流

非正式途径:清晰定义小组内部的相互关系和充分利用电话,能鼓励大量的电话沟通,从而达到对所书写文档的共同理解。

会议:常规项目会议。会议中,团队一个接一个地进行简要的技术陈述。这种方式非常有用,能澄清成百上千的细小误解。

工作手册:在项目的开始阶段,应该准备正式的项目工作手册。理所应当,我们专门用一节来讨论它。

产品测试

设立测试小组是使设计决策得以贯彻执行的必要手段,同样也是需要尽早着手,与设计同时实施的重要环节

团队组织

团队组织的目的是减少不必要交流和合作的数量,因此良好的团队组织是解决上述交流问题的关键措施。 减少交流的方法是人力划分(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)

编成的工作量

时间规划

计划

编制文档

测试

系统集成

培训的时间

因此,上述小型项目数据的外推是没有意义的。就好像把100码短跑记录外推,得出人类可以在3分钟之内跑完1英里的结论一样。

计算机产品文档

目标:定义待满足的目标和需要,定义迫切需要的资源、约束和优先级。

技术说明:计算机手册和性能规格说明。它是在计划新产品时第一个产生,并且最后完成的文档。进度、时间表

预算:预算不仅仅是约束。对管理人员来说,它还是最有用的文档之一。预算的存在会迫使技术决策的制订,否则,技术决策很容易被忽略。更重要的是,它促使和澄清了策略上的一些决定。

做什么:目标。定义了待完成的目标、迫切需要的资源、约束和优先级。

做什么:产品技术说明。以建议书开始,以用户手册和内部文档结束。速度和空间说明是关键的部分。

时间:进度表

资金:预算

地点:工作空间分配

人员:组织图。它与接口说明是相互依存的,如同Conway的规律所述:“设计系统的组织架构受到产品的约束限制,生产出的系统是这些组织机构沟通结构的映射。1”Conway接着指出,一开始反映系统设计的组织架构图,肯定不会是正确的。如果系统设计能自由地变化,则项目组织架构必须为变化做准备。

目的。主要的功能是什么?开发程序的原因是什么?

环境。程序运行在什么样的机器、硬件配置和操作系统上?

范围。输入的有效范围是什么?允许显示的合法范围是什么?

实现功能和使用的算法。精确地阐述它做了什么。

输入-输出格式。必须是确切和完整的。

操作指令。包括控制台及输出内容中正常和异常结束的行为。

选项。用户的功能选项有哪些?如何在选项之间进行挑选?

运行时间。在指定的配置下,解决特定规模问题所需要的时间?

精度和校验。期望结果的精确程度?如何进行精度的检测?

项目经理的任务是制订计划,并根据计划实现。但是只有书面计划是精确和可以沟通的。

手册、或者书面规格说明,是一个非常必要的工具,尽管光有文档是不够的。手册是产品的外部规格说明,它描述和规定了用户所见的每一个细节;同样的,它也是结构师主要的工作产物。

规格说明的风格必须清晰、完整和准确。

用户常常会单独提到某个定义,所以每条说明都必须重复所有的基本要素,所以所有文字都要相互一致。这往往使手册读起来枯燥乏味,但是精确比生动更加重要。

项目所有的文档都必须是该结构的一部分。这包括

目的

外部规格说明

接口说明

技术标准

内部说明

管理备忘录。

总结:\t1. 必须做好手册、外部规格书,定义好明确完整个功能\t2. 要有一定的写作规范,文字相互一致。

未雨绸缪

新的系统概念或新技术会不断出现,所以开发的系统必须被抛弃,但即使是最优秀的项目经理,也不能无所不知地在最开始解决这些问题。

为舍弃而计划,无论如何,你一定要这样做。

如何为上述变化设计系统,是个非常著名的问题,在书本上被普遍讨论——可能讨论得比实践还要多得多。它们包括细致的模块化、可扩展的函数、精确完整的模块间接口设计、完备的文档

原因在于编写的人和维护的人不同,若要减少缺陷修复的bug,测试用例做好,维护的人减少、接口减少(接口减少难以时间).

维护:维护总成本通常是开发成本的40%或更多。缺陷修复总会以(20-50)%的机率引入新的bug。

出现bug的数量是发布时间的函数

修复工作迟早会失去根基,重新设计是完全必要的

干将莫邪

保管好自己的一套工具。实用程序、调试辅助程序、测试用力生产工具、处理文档系统

测试规格说明

在编写代码之前,规划说明必须提交给测试小组,详细检查说明的完整性和正确性。

阶段(量子)要么很大,间隔很宽 vs 小而频繁,根据他们的模型,小而频繁的阶段很容易变得不稳定

分成三个部分。

针对遇到的大多数常规数据和程序主要功能进行测试的用例。它们是测试用例的主要组成部分。

数量相对较少的合法数据测试用例,对输入数据范围边界进行检查,确保最大可能值、最小可能值和其他有效特殊数据可以正常工作。

数量相对较少的非法数据测试用例,在边界外检查数据范围边界,确保无效的输入能有正确的数据诊断提示。 修改程序。调整程序或者修复程序需要更多的信息。显然,这要求了解全部的细节,并且这些细节已经记录在注释良好的列表中。和一般用户一样,修改者迫切需要一份清晰明了的概述,不过这一次是关于系统的内部结构。那么这份概述的组成部分是什么呢?

流程图或子系统的结构图,对此以下有更详细的论述。

对所用算法的完整描述,或者是对文档中类似描述的引用。

对所有文件规划的解释。

数据流的概要描述——从磁盘或者磁带中,获取数据或程序处理的序列——以及在每个处理过程完成的操作。

初始设计中,对已预见修改的讨论;特性、功能回调的位置以及出口;原作者对可能会扩充的地方以及可能处理方案的一些意见。另外,对隐藏缺陷的观察也同样很有价值。

总结:开发时间间隔够宽、编码前需要测试小组,详细检查说明的完整性与正确性。

祸起萧墙

减少角色冲突,鼓励状态共享:

猛地拉开地毯: 两者都为监督检查目前工作进度,以PERT图建立里程碑,里程碑越清楚越好,且时时检查,若有延迟则即时提出解决方案。

PERT图

总结:必须先定义好 PERT 图与里程碑,时时检查目前进度,并且时时解决方法。

没有银弹

产品目的

仔细地进行市场调研,避免开发已上市的产品。

开发过程

在获取和制订软件需求时,将快速原型开发作为迭代计划的一部分。

有机地更新软件,随着系统的运行、使用和测试,逐渐添加越来越多的功能。

不断挑选和培养杰出的概念设计人员。

购买和自行开发。构建软件最可能的彻底解决方案是不开发任何软件

以上提到的任何软件,购买都要比重新开发要低廉一些。即使支付100,000美元,购买的软件也仅仅是一个人年的成本。而且软件是立即可用的!至少对于现有的产品、对于那些专注于该领域开发者的成果而言,它们是可以立刻投入使用的

人才

寻求培养卓越设计人员的途径。杰出的设计人员和卓越的管理人员一样重要,他们应该得到相同的培养和回报。不仅仅是薪资

尽可能早地、有系统地识别顶级的设计人员。最好的通常不是那些最有经验的人员。

为设计人员指派一位职业导师,负责他们技术方面的成长,仔细地为他们规划职业生涯。

为每个方面制订和维护一份职业计划,包括与设计大师的、经过仔细挑选的学习过程、正式的高级教育和以及短期的课程——所有这些都穿插在设计和技术领导能力的培养安排中。

为成长中的设计人员提供相互交流和学习的机会。

读书总结

目录

开发流程

人力安排

人才培育