人月神话
IBM System/360系統之父 佛瑞德·布魯克斯(Frederick Phillips Brooks, Jr) 所著經典文集。 软体工程的神品。40周年中文纪年版。
全球最大的软件消费者(美国军方)每年买数十亿美元购买软件,其购买直接使用的只有 2%,另外 3%需要一些修改,其他 95% 垃圾。他们显然没有很满足客户的需求。
完整程序
水平边界以下,程序变成编程产品(Programming Product)。 这是可以被任何人运行、测试、修复和扩展的程序。它可以运行在多种操作系统平台上,供多套数据使用。要成为通用的编程品。
垂直边界的右边,程序变成编程系统(Programming System)中的一个构件单元。它是在功能上能相互协作的程序集合,具有规范的格式,可以进行交互,并可以用来组装和搭建整个系统。
当要做一个完整的程序需要 3 * 3 = 9 工作量。
人月神话
当意识到进度的偏移时,下意识(以及传统)的反应是增加人力。这就像使用汽油灭火一样,只会使事情更糟。解释如下:
人数和时间的互换仅仅适用于以下情况:某个任务可以分解给参与人员,并且他们之间『 不需要相互的交流 』。
当任务由于次序上的限制不能分解时,人手的添加对进度没有帮助。
一对一交流的情况下,三个人的工作量是两个人的三倍,四个人则是两个人的六倍。
以两个人的工作量以此类推,则工作量按照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。
修复工作迟早会失去根基,重新设计是完全必要的
干将莫邪
保管好自己的一套工具。实用程序、调试辅助程序、测试用力生产工具、处理文档系统
测试规格说明
在编写代码之前,规划说明必须提交给测试小组,详细检查说明的完整性和正确性。
阶段(量子)要么很大,间隔很宽 vs 小而频繁,根据他们的模型,小而频繁的阶段很容易变得不稳定
分成三个部分。
针对遇到的大多数常规数据和程序主要功能进行测试的用例。它们是测试用例的主要组成部分。
数量相对较少的合法数据测试用例,对输入数据范围边界进行检查,确保最大可能值、最小可能值和其他有效特殊数据可以正常工作。
数量相对较少的非法数据测试用例,在边界外检查数据范围边界,确保无效的输入能有正确的数据诊断提示。 修改程序。调整程序或者修复程序需要更多的信息。显然,这要求了解全部的细节,并且这些细节已经记录在注释良好的列表中。和一般用户一样,修改者迫切需要一份清晰明了的概述,不过这一次是关于系统的内部结构。那么这份概述的组成部分是什么呢?
流程图或子系统的结构图,对此以下有更详细的论述。
对所用算法的完整描述,或者是对文档中类似描述的引用。
对所有文件规划的解释。
数据流的概要描述——从磁盘或者磁带中,获取数据或程序处理的序列——以及在每个处理过程完成的操作。
初始设计中,对已预见修改的讨论;特性、功能回调的位置以及出口;原作者对可能会扩充的地方以及可能处理方案的一些意见。另外,对隐藏缺陷的观察也同样很有价值。
总结:开发时间间隔够宽、编码前需要测试小组,详细检查说明的完整性与正确性。
祸起萧墙
减少角色冲突,鼓励状态共享:
猛地拉开地毯: 两者都为监督检查目前工作进度,以PERT图建立里程碑,里程碑越清楚越好,且时时检查,若有延迟则即时提出解决方案。
总结:必须先定义好 PERT 图与里程碑,时时检查目前进度,并且时时解决方法。
没有银弹
产品目的
仔细地进行市场调研,避免开发已上市的产品。
开发过程
在获取和制订软件需求时,将快速原型开发作为迭代计划的一部分。
有机地更新软件,随着系统的运行、使用和测试,逐渐添加越来越多的功能。
不断挑选和培养杰出的概念设计人员。
购买和自行开发。构建软件最可能的彻底解决方案是不开发任何软件
以上提到的任何软件,购买都要比重新开发要低廉一些。即使支付100,000美元,购买的软件也仅仅是一个人年的成本。而且软件是立即可用的!至少对于现有的产品、对于那些专注于该领域开发者的成果而言,它们是可以立刻投入使用的
人才
寻求培养卓越设计人员的途径。杰出的设计人员和卓越的管理人员一样重要,他们应该得到相同的培养和回报。不仅仅是薪资
尽可能早地、有系统地识别顶级的设计人员。最好的通常不是那些最有经验的人员。
为设计人员指派一位职业导师,负责他们技术方面的成长,仔细地为他们规划职业生涯。
为每个方面制订和维护一份职业计划,包括与设计大师的、经过仔细挑选的学习过程、正式的高级教育和以及短期的课程——所有这些都穿插在设计和技术领导能力的培养安排中。
为成长中的设计人员提供相互交流和学习的机会。
读书总结
目录
开发流程
人力安排
人才培育
閱讀更多 潘江 的文章