摘录与 《人月神话》

什么是人月神话?

一个项目有10人/月的工作量,把人增加到100人,所以只用3天就能开发完,这就是人月神话。

一个谬误的思考方式是在估计和进度安排中使用的工作量单位:人月。成本的确随开发产品的人数和时间的不同,有着很大的变化,进度却不是如此。因此我认为用人月作为衡量一项工作的规模是一个危险和带有欺骗性的神话。它暗示着人员数量和时间是可以相互替换的。

一、焦油坑(The Tar Pit)

史前史中,没有别的场景比巨兽在焦油坑中垂死挣扎的场面更令人震撼。上帝见证着恐龙、猛犸象、剑齿虎在焦油中挣扎。它们挣扎得越是猛烈,焦油纠缠得越紧,没有任何猛兽足够强壮或具有足够的技巧,能够挣脱束缚,它们最后都沉到了坑底。

过去几十年的大型系统开发就犹如这样一个焦油坑,很多大型和强壮的动物在其中剧烈地挣扎。他们中大多数开发出了可运行的系统–不过,其中只有非常少数的项目满足了目标、时间进度和预算的要求。各种团队,大型的和小型的,庞杂的和精干的,一个接一个淹没在了焦油坑中。

编程系统产品(Program System Product)

演化进程:程序->编程系统(接口、系统集成)->编程系统产品;程序->编程产品(通用化、测试、文档、维护)->编程系统产品。这两条线都节约了成本。

编程的乐趣

  • 首先是一种创建事物的纯粹快乐。如同小孩在玩泥巴时感到愉快一样,成年人喜欢创建事物,特别是自己进行设计。我想这种快乐是上帝创造世界的折射,一种呈现在每片独特、崭新的树叶和雪花上的喜悦1。
  • 其次,快乐来自于开发对其他人有用的东西。内心深处,我们期望其他人使用我们的劳动成果,并能对他们有所帮助。从这个方面,这同小孩用粘土为”爸爸办公室”捏制铅笔盒没有本质的区别。
  • 第三是整个过程体现出魔术般的力量–将相互啮合的零部件组装在一起,看到它们精妙地运行,得到预先所希望的结果。比起弹珠游戏或点唱机所具有的迷人魅力,程序化的计算机毫不逊色。
  • 第四是学习的乐趣,来自于这项工作的非重复特性。人们所面临的问题,在某个或其它方面总有些不同。因而解决问题的人可以从中学习新的事物:有时是实践上的,有时是理论上的,或者兼而有之。
  • 最后,乐趣还来自于工作在如此易于驾驭的介质上。程序员,就像诗人一样,几乎仅仅工作在单纯的思考中。程序员凭空地运用自己的想象,来建造自己的”城堡”。很少有这样的介质–创造的方式如此得灵活,如此得易于精炼和重建,如此得容易实现概念上的设想。(不过我们将会看到,容易驾驭的特性也有它自己的问题)然而程序毕竟同诗歌不同,它是实实在在的东西;可以移动和运行,能独立产生可见的输出;能打印结果,绘制图形,发出声音,移动支架。神话和传说中的魔术在我们的时代已变成了现实。在键盘上键入正确的咒语,屏幕会活动、变幻,显示出前所未有的或是已经存在的事物。

编程的苦恼

  • 首先,必须追求完美。因为计算机也是以这样的方式来变戏法:如果咒语中的一个字符、一个停顿,没有与正确的形式一致,魔术就不会出现。(现实中,很少的人类活动要求完美,所以人类对它本来就不习惯。)实际上,我认为学习编程的最困难部分,是将做事的方式往追求完美的方向调整。
  • 其次,是由他人来设定目标,供给资源,提供信息。编程人员很少能控制工作环境和工作目标。用管理的术语来说,个人的权威和他所承担的责任是不相配的。不过,似乎在所有的领域中,对要完成的工作,很少能提供与责任相一致的正式权威。而现实情况中,实际(相对于正式)的权威来自于每次任务的完成。
  • 概念性设计是有趣的,但寻找琐碎的bug却只是一项重复性的活动。
  • 人们发现调试和查错往往是线性收敛的,或者更糟糕的是,具有二次方的复杂度。结果,测试一拖再拖,寻找最后一个错误比第一个错误将花费更多的时间。
  • 当投入了大量辛苦的劳动,产品在即将完成或者终于完成的时候,却已显得陈旧过时。可能是同事和竞争对手已在追逐新的、更好的构思;也许替代方案不仅仅是在构思,而且已经在安排了。

二、人月神话(The Mythical Man-Month)

项目滞后的主要原因是缺乏进度的合理安排:

  • 对估算技术缺乏有效研究。乐观主义,通常假设一切都将运作良好;
  • 混淆工作量和进度,以为人月可以互换;
  • 对自己的估算缺乏信心,项目经理不会耐心持续的进行估算;
  • 缺少进度跟踪和监督;
  • 进度偏移时,第一反应是协调人力。
  1. 乐观主义,乐观主义是程序员的职业病。
  2. 人月,人员之间的需要沟通交流,新派人手可能成为负担;而且任务还有先后顺序。
  3. 系统测试,过程时间占比经验:
    • 计划(1/3):包含技术调研、概念设计(功能规格)
    • 编码(1/6):最容易估计时间的部分
    • 构件测试和早起系统测试(1/4):单元测试
    • 系统测试(1/4):集成测试
  4. 空泛的估算,在外部的压力下,项目经理在估算时容易屈服。开发并推行生产率图表、缺陷率图表、估算规则等工具可以使得项目估计更有依据,相比经验也更能有说服力。
  5. 重复产生的进度灾难,进度延迟后考虑的做法:
    • 重新安排进度:注意在开发过程中及时重新估计和调整进度(不一定是延后,而是根据实际情况,部分任务缩减,部分任务延长),任务的粒度也需要注意,不需要太细,也不能太粗。
    • 削减任务:讨论功能的重要性和优先级,考虑分版本发布,先完成重要、紧急的功能。

Brooks法则:想落后的项目中增加人手,只会使得进度更加落后。

三、外科手术队伍(The Surgical Team)

  • 优秀程序员的生产率是一般程序员的10倍
  • 小型精干的团队是最好的
  • 对于大型的系统,小型精干的团队速度太慢了
  • 类似外科手术的团队能很好解决大型系统开发的问题
  1. 问题,小型精干队伍的人数一般在10人以内。但是对于大型系统,比如需要1000人年,完成项目的进度显得太长对于大型系统,需要划分模块来完成。而且概念设计部分需要由少而精的人员完成。
  2. Mills的建议(外科手术队伍):
    • 外科医生(架构师):定义功能、性能技术说明书,设计程序,编写源代码,测试,写技术文档;
    • 副手(开发组长):能完成任何一部分工作,但经验较少。设计的思考者、讨论者、评估人员;
    • 管理员(项目经理):管理财务、人员、办公设备等,可以一个人管两个项目组;
    • 编辑:组织文档;
    • 两个文秘:管理员和编辑各一个(偶也想要啊)
    • 程序职员:维护所有团队的技术记录
  3. 如何运作,概念来自外科医生和副手,保证了完整性并节约了沟通成本,外科医生在金字塔顶端,可以统一分歧,其余人员分工专业化,更为高效
  4. 团队的扩建,大型系统需要一个系统结构师自上而下的进行所有设计,也有利于协调。概念设计团队的人也要少而精。

四、贵族专制、民主政治和系统设计(Aristocracy, Democracy, and System Design)

  • 概念完整性是系统设计中最重要的因素
  • 为了保证概念完整性,设计必须由一个人或一个小型的团队
  • 软件开发要实现设计和具体实现的分离
  • 限制和规则能激发创造性
  • 概念统一的系统能更快的开发和测试

概念完整性

概念完整性应该是系统设计最重要的考虑因素。保证概念完整性最好的方法是由一个人来完成设计,对于后来的设计者,则要求他们牺牲一些创意,以获得纯粹的设计。

获得概念完整性

系统设计的最终测试标准:易用性 = 功能 / 理解复杂度。

软件不仅要功能越多越好,而且需要简洁、直接。简洁和直白来自概念完整性。

设计的一致性是易用性的另一重要因素。设计一致性要求:每个部分必须反映相同的原理需求的一致平衡(语法上使用的技巧相同,语义上也要具有相似性)。

贵族专制和民主政治

概念的完整性要求设计必须由一个人,或者少数互有默契的人员来实现。但进度压力要求系统要由很多人来开发。解决这一矛盾的方法有两个:仔细对设计方法/体系结构与具体实现进行分工;第三章所述的团队的组建方式。

系统的体系结构(achitecture)指的是完整和详细的用户接口说明。系统的结构师(架构师)需要运用专业技术知识来支持最终用户的利益。

体系结构师(架构师)的贵族专制统治:体系结构师代表最终用户的利益;其产物的生命周期比实现人员更长;为了概念完整性,系统设计必须由少数人(架构师)控制。

具体设计实现在创造性方面并不亚于体系结构设计工作:具体实现更大程度决定了产品的成本和性能;而结构设计偏向于易用性。但是具体实现需要依赖于结构设计。

在等待时,实现人员应该做什么

软件开发的三个阶段(Blaauw):体系结构(achitecture)、设计实现(implementation)、物理实现(realization)。他们彼此存在依赖,但往往可以同时开始和并发进行。

上述的划分是水平的划分,实际中再进行垂直的(功能)划分并不会在概念完整性等方面造成不利影响。上述的三个阶段确实存在一定的向上依赖,但是垂直的划分使得工作可以并行进行;另外各个阶段中都有部分工作是不存在向上依赖的。

五、画蛇添足(The Second-System Effect)

  • 不要过分设计

    结构师的主要职责在于只能功能规格说明,他没有产品开发时间、成本方面的责任。理论上结构师的创造性可以是无限的,那么如何来约束这种热情呢?

结构师的交互准则和机制

今早的交流和持续沟通:使得结构师有成本意识,也让开发人员对设计有信心,不会混淆责任分工。

产生估算过高时,结构师有两个选择:削减设计;建议实现人员使用成本更低的实现方法。

交互准则:

  • 牢记开发人员承担实现的责任,所以只能建议,不能支配;
  • 时刻准备为所指定的功能建议一种实现方法,同样准备接受其他任何能够达到目标的方法;
  • 对上述的建议保持低调和不公开;
  • 准备放弃坚持所做的改进建议;
  • 在体系结构上的修改往往会引起开发人员的反对——实现工作展开时,一些次要特性的修改会造成意想不到的成本开销。

自律——开发第二个系统所带来的后果

结构师设计的第二个系统往往是最危险的。

由于对任务不够了解而产生的谨慎,结构师的第一个系统倾向于精炼和简洁;而第二个系统往往会被过分设计(太多的修饰功能、想法);后面的项目会在之前的经验上形成对比总结,所以在简洁性和功能方面,比较容易达到平衡。避免过分设计的方法在于:自律和程序经理的监督。

六、贯彻执行(Passing the Word)

  • 设计必须由一个或两个人负责,确保设计的一致性
  • 具体精确的定义系统和功能

文档化的规格说明——手册

手册需要描述和规定用户所见的每一个细节,同时需要避免描述用户不可见的部分。结构师必须为自己描述的任何特性准备一种实现方法,但不应试图支配实现过程。

手册(规格说明)的风格必须清晰、完整和准确。一致性很重要。

形式化定义

形式化(术语化、公式化)定义是精确的,倾向完整;但是不易理解,需要记叙性文字的辅助。注意在同一个手册中需要在谁主谁辅上保持一致。

实现可以作为一种形式化定义方法(如)。实现作为形式化定义的优点:所有问题可以通过试验清晰的得到答案,快捷迅速、无需争辩商讨;缺点:实现作为定义时,体现了过多的内容,即不但描述了系统必须做什么,同时还声明了自己做了些什么(多余的要求)。

直接整合

设计好模块间接口的原型,要求在实现过程中按照原型开发。

会议和大会

周例会:每周半天,由首席结构师主持,所有结构师参加、实现人员代表和市场计划人员(代表用户)参与。参与人员都可以提出问题和修改意见,但需要提前准备并分发书面建议书。讨论通过的建议/问题解决方案由相关结构师进行修改,并纳入变更建议说明书中。问题结论由首席架构师发布。

周例会优点:相同人员数月内每周交流一次,对项目内容都比较了解,无需额外培训;参与人员与产品密切相关,深刻理解所面对的问题,每个人都承担义务;出现问题时,在界线内部和外部同时寻求解决方案;正式的书面建议集中了注意力,强制了决策的制定和执行;明确授予首席结构师决策权力,避免妥协拖延。

年度(或半年)大会,在功能规格制定前进行。出了周例会成员,程序经理、实现人员、市场人员都会参与,由项目经理主持。集中解决遗留的各种问题,耗时两周,每天需要通知前一天的各项决定。

年度大会优点:解决了部分决策上的问题,同时使决策更容易被接受和理解。

多重实现

多重实现时,根据机器修改手册的消耗可能比根据手册修改机器要高。

电话日志

实现人员对规格说明容易理解不当或规格说明本身描述就不够精确,所以结构师鼓励实现人员电话沟通。在此条件下,结构师需要保存电话日志,记录每个问题和相应的解答,并每周进行合并整理,分发给用户和实现人员。

产品测试

测试组的工作是根据规格说明检查程序,需要由独立的技术监督部门完成,以保证公正性。

七、为什么巴比伦塔会失败?(Why Did theTower of Babel Fail?)

  • 失败的原因:交流
  • 团队应该尽可能多的交流
  • 制定良好的工作手册
  • 每一个团队成员都应该能看到所有材料
  • 每个团队两个领导,技术负责人和产品负责人

 巴比伦塔(圣经中的典故):开始,人们使用的是同一种语言,他们建造房屋,并想着建造一个有高塔的城市,所有人都可以聚集在高塔里。上帝听说后,认为有必要让人类经历些挫折,于是他在人类的语言中制造了混淆,相互无法听懂。这样人类就不得不停止制造巴比伦塔。

巴比伦塔的管理教训

人类有清晰的目标、人力充足、材料齐全、时间充裕、技术完备。但失败的原因在于:缺乏交流以及交流的结果(组织)。

大型编程项目中的交流

团队之间的交流沟通需要利用所有可能的途径:

  • 非正式途径:电话、口头、即时通讯、邮件等;
  • 会议:各团队逐一进行简要的技术陈述。很容易澄清细小的误解;
  • 工作手册:在项目开始阶段即应该准备

项目工作手册

定义:对项目必须产出的一系列文档进行组织的一种结构,而非独立的一篇文档。即定义各类文档存放在什么位置。

备忘录的管理:编号、整理,便于检索。

当编程人员仅了解自己负责的部分,而非整个系统的开发细节时,工作效率最高。此方法的先决条件在于精确完整的定义所有接口。

大型变成项目的组织架构

团队组织的目的:减少所需的交流和合作的数量。

减少交流的方法:人力划分和限定职责范围。

树状组织架构是作为权力和责任的结构出现,不适合交流和沟通(网状)。

树状编程队伍中,每颗子树必备的基本要素:任务(mission);产品负责人(producer);技术主管或结构师(techenical director or architecture);进度(schedule);人力划分(division of labor);各部分间的接口定义(interface definitions among the parts)。

产品负责人:组建团队、划分工作、制定进度表。争取和保证必要的资源(外部向上或水平沟通);建立内部沟通/报告方式;确保进度目标的实现,根据环境变化调整资源和团队架构。

技术主管:对设计进行构思,识别系统的字部分,设计内部结构和外部功能;提供整个设计的一致性和概念完整性;控制系统的复杂程度。提供复杂问题的解决方案,或根据需要调整系统设计。

建议技术主管为主,产品负责人为辅的组织架构;产品负责人为主时需要预先声明技术主管在技术决策方面的权威(亦可通过办公条件等方面暗示)。

八、胸有成竹(Calling the Shot)

  • 仅仅靠编码时间乘以系数是无法得到完成时间的
  • 小项目的数据不适用于大项目,开发时间随项目大小呈指数增长
  • 使用高级语言的效率是使用汇编语言5倍

系统编程的时间估计,工作量估计方法:比率估算法(不能仅用编码阶段估计);小型程序数据不适合编程系统产品。

他发现他的编程队伍落后进度大约1/2,每项工作花费的时间大约是估计的两倍。这些估计通常是非常仔细的,由很多富有经验的团队完成。他们对PERT图上数百个子任务估算过(用人小时作单位)。当偏移出现时,他要求他们仔细地保存所使用时间的日志。日志显示事实上他的团队仅用了百分之五十的工作周,来进行实际的编程和调试,估算上的失误完全可以由该情况来解释。其余的时间包括机器的当机时间、高优先级的无关琐碎工作、会议、文字工作、公司业务、疾病、事假等等。简言之,项目估算对每个人年的技术工作时间数量做出了不现实的假设。我个人的经验也在相当程度上证实了他的结论6。

九、削足适履(Ten Pounds in a Five-Pound Sack)

  • 仅仅靠编码时间乘以系数是无法得到完成时间的
  • 小项目的数据不适用于大项目,开发时间随项目大小呈指数增长
  • 使用高级语言的效率是使用汇编语言5倍

十、提纲挈领(The Documentary Hypothesis)

在一片文件的汪洋中,少数文档形成了关键的枢纽,每件项目管理的工作都围绕着它们运转。它们是经理们的主要个人工具。

  • 文档的关键,目标,用户手册,内部文档,进度,预算,组织结构图和工作空间分配
  • 为每个关键文档提供状态监督和语境机制
  • 项目经理的职责是使每个人都朝着同一个方向前进
  • 项目经理的日常工作是沟通而不是做决定

前提:在堆积如山的文档中,少数是关键枢纽,每一件项目管理工作都围绕着他们运转。这些文档是项目经理最重要的个人工具。

技术、周边组织机构、行业传统等因素定义了项目必须准备的一些文书工作。这些文书工作看起来令人厌烦,但是他们往往包含了一些管理方面的内容:每份文档的准备工作是集中考虑,并使各种讨论意见明朗化的主要时刻;文档有利于明确工作阶段;文档的跟踪维护是项目监督和预警机制;文档本身可以作为检查列表、状态控制,也可以作为汇报的数据基础。

任何管理任务的关注焦点都是:时间、地点、人员、项目内容、资金。

  1. 软件项目文档

内容:目标。定义待完成的目标、迫切需要的资源、约束和优先级;

内容:产品技术说明。以建议书开始,用户手册和内部文档结束。性能说明是关键部分;

时间:进度;

资金:预算;

地点:工作空间分配;

人员:组织图。人员与接口说明相互依存。组织结构需要根据系统设计自由变化。

  1. 为什么要有正式的文档

书面记录决策是必要的。记录文档可以作为同其他人沟通的渠道。项目经理的基本职责是使每个人都想着相同的方向前进,其主要工作是沟通,非决定。

文档可以作为数据基础和检查列表。通过文档能够搞清项目所处状态,需要做的更改和调整。

文档非常重要,但是不存在“完全信息管理系统”。因为管理人员80%的时间都用在沟通上:倾听、报告、讲授、规劝、讨论和鼓励。

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

十一、未雨绸缪(Plan to Throw One Away)

不变只是愿望,变化才是永恒。

  • 开发人员交付的是用户满意度而不是实际的产品
  • 用户的实际需要会不断变化
  • 前进两步,后退一步,维护会增加系统的复杂性和引入新的Bug。
  1. 试验性工厂和增大规模

    必须为舍弃而计划。第一个版本必然会存在很多问题,所以做好把其当做一个试验品的准备。要注意试验品是否应当发布给用户。

  1. 唯一不变的是变化本身

    接受变化,但并非客户所有的需求变更都应该整合到设计中。

  1. 为变更计划系统

    技术手段:设计细致的模块化、可扩展的函数、精确完整的模块间接口设计和完备的文档。

    变更的阶段化:版本号、日程表、冻结日期、变更内容。

  2. 为变更计划组织架构

    选择高效的技术人员,解决各种技术问题;对技术人员进行培训;废除职位头衔,让成员能够接受职务变更。

  3. 前进两步,后退一步

    缺陷修复总会以20%-50%的概率引入新的Bug;

    回归测试的成本很高;

    选择程序设计方法时,需要考虑其副作用,并指明。

  4. 前进一步,后退一步

    在系统维护过程中,更多关注的是功能实现,系统原有设计日益被忽略,每次的修改都可能导致潜在的新问题,修改成本日益增加。必要时,需要考虑代码重构或重新设计。

十二、干将莫邪(Sharp Tools)

巧匠因为他的工具而出名。

  • 项目成员要使用通用开发工具

工具要通用化,个性化的工具妨碍沟通。建议每个团队一个工具管理人员,工具小组方式则相对效率更低。

考虑使用高级语言、成熟框架,性能测试工具,调试工具,测试用例生成工具等。

十三、整体部分(The Whole and the Parts)

  • 有时必须推翻顶层,重新开始

剔除Bug的设计

系统各个部分的开发者都会做出假设,这些假设的不匹配会导致致命或难以察觉的Bug。细致的功能定义、仔细的规格说明、规范化的功能描述说明很有必要。

测试规格说明:完整性和明确性

自上而下的设计,横向划分为:体系结构设计、设计实现、物理实现;纵向以模块划分,且模块从大到小不断细化。优点:

  • 清晰的结构和表达方式更容易对需求和模块功能进行精确的描述;
  • 模块分割和模块独立性避免了系统级Bug;
  • 细节的抑制使得结构上的缺陷容易暴露出来;
  • 设计在每个精化步骤上都是可测试的。
  • 遇到极端问题时,可能需要考虑逆转过程,直至推翻顶层设计,重新开始。

单元调试

程序调试过程在过去的二十年中有过很多反复,甚至在某些方面,它们又回到了出发的起点。整个调试过程有四个步骤,跟随这个过程来检验每个步骤各自的动机是一件很有趣的事情。  

系统集成调试

需要在各个部分都能够正常运行之后开始。这个阶段耗费的时间往往比预计的要长。

使用伪构件(dummy component,包含接口、可能的伪数据和一些小的测试用例)。

控制变更。控制构件单元版本。

一次添加一个构件。能够有利于问题定位。

阶段化变更。定期进行大范围的构件更新等,周期不宜太短。

十四、祸起萧墙(Hatching a Catastrophe)

带来坏消息的人不受欢迎。

  • 项目进度的落后是潜移默化的,因此必须设置阶段目标

里程碑还是沉重的负担

里程碑澄清了划分的比较模糊的阶段,定义了确定时间点需要的完整的产物。里程碑的边界需要是明显的,无歧义的。里程碑需要能够正确的反应损失的时间,避免慢性进度偏离影响士气。

建议活动之前开始估计,每两周对计划进行一次仔细的修订。

关键路径法(Pert图)

那些任务的滞后会影响最终的完成日期。非关键任务允许一定的落后时间。

相对对每个任务估计完成时间,关键路径法更能够鼓励超前完成,也指明了补偿其他任务滞后时间的方法。

地毯的下面

程序经理发现计划偏离时,存在于老板的利益冲突:老板需要行动计划,分析的状态数据;程序经理会认为非致命性的进度偏离是可通过团队内部解决的,老板的行动可能会影响计划或个人威信。冲突(让程序经理公开信息)的解决方法:

减少角色冲突:老板避免对程序经理能够解决的问题进行干预,绝不在检查状态报告时做安排。

猛地拉开地毯:评审机制。每周小屏,每月大评。项目经理需要解释延迟原因,并指出应对方案和需要的帮助。

十五、另外一面(The other face)

  • 文档很重要,不论程序员还是用户
  • 自文档化技术,文档编写要和源代码结合起来,文档以注释的形式存在

对开发人员光是介绍文档的重要性,并讲解写文档的技巧和要点,还不如做一份给他们看。

需要什么样的文档

使用程序的文档内容:

  • 目的(程序的主要功能是什么,解决了什么问题);
  • 环境(机器、硬件配置、操作系统等);
  • 输入范围,输出范围;
  • 实现功能和使用的算法;
  • 输入-输出格式(必须是确切完整的);
  • 操作指令;
  • 功能选项;
  • 运行时间;
  • 精度和校验;
  • 精度及如何校验精度。
  • 验证程序的文档内容:
  • 测试用例。给程序使用者提供信心。
  • 修改程序文档内容:
  • 流程图或子系统的结构图;
  • 对所用算法的完整描述;
  • 对所有文件规划的解释;
  • 数据流处理的概要描述,以及每个处理过程中晚餐的操作;
  • 初始设计中,对已遇见修改的讨论;特性、功能回调以及出口的位置;原作者对可能会修改的地方及可能处理方案的一些意见。

流程图

从代码生成流程图非良好实践。

自文档化的程序

维护文档和代码的一致性是费力不讨好的事情。建议将注释以文字记录到代码头部,注意格式。维护记录也可记录其中。

十六、没有银弹——软件工程中的根本和次要问题

在未来十年内,无论是在技术还是管理方法上,都看不出有任何突破性的进步,能够独自保证在十年内大幅度地提高软件的生产率、可靠性和间接性

软件活动包括:

  • 根本任务,打造构成抽象软件实体的复杂概念结构
  • 次要任务,使用编程语言表达这些抽象实体,在空间和时间限制内将它们映射成机器语言。

作者出于必要任务考虑的四点建议:

  • 仔细进行市场调研,避免开发已上市的产品;
  • 获取和制定软件需求时,将快速原型开发作为迭代计划的一部分;
  • 有机地更新软件,随着系统的运行、使用和测试,逐渐添加越来越多的功能;
  • 不断挑选和培养杰出的概念设计人员。

根本困难

软件开发困难的部分:规格说明、设计和测试这些概念结构,而非对概念进行表达和对实现逼真程度进行验证。

软件内在特性:复杂度、一致性、可变性和不可见性。

次要问题上的突破

  • 高级语言;
  • 统一的编程环境。

银弹的希望

  • 高级语言;
  • 面向对象编程;
  • 人工智能;
  • 专家系统;
  • “自动”编程;
  • 图形化编程;
  • 程序验证;
  • 环境和工具。

针对根本问题颇有前途的方法

  • 购买而非自行开发
  • 需求精炼和快速原型
  • 增量开发——增长而非搭建系统。
  • 卓越的设计人员
  • 杰出设计人员的培养方法:
  • 尽可能早的,有系统的识别顶级的设计人员;
  • 为设计人员指派一位职业导师,负责他们技术方面的成长,仔细为他们规划职业生涯;
  • 为每个方面制定和维护一份职业计划,包括设计大师的精挑细选的学习过程,正式的高级教育和短期的课程;
  • 为成长中的设计人员提供相互交流和激励的机会。