[人月神话]读书笔记8--软件产品需要的文档&&软件开发没有银弹(捷径)

另外一面(The other face)

★需要什么样的文档

书面的计算机程序还有其他的呈现面貌,向用户诉说自己的故事。即使是完全开发给自己使用的程序。这种沟通仍然是必要的。因为记忆衰退的规律会使用户作者失去对程序的了解。
对软件编程产品来说,程序向用户所呈现的面貌和提供给机器识别的内容同样重要

□使用程序。
不同用户需要不同级别的文档。某些用户仅仅偶尔使用程序,用些用户必须依赖程序,还有一些用户必须根据环境和目地的变动对程序进行修改。
一份有用的文字描述,包括以下的内容。
1. 目的。主要的功能是什么?开发程序的原因是什么?
2. 环境。程序运行在什么样的机器、硬件配置和操作系统上?
3. 范围。输入的有效范围是什么?允许显示的合法范围是什么?
4. 实现功能和使用的算法。精确地阐述它做了什么。
5. 输入-输出格式。必须是确切和完整的。
6. 操作指令。包括控制台及输出内容中正常和异常结束的行为。
7. 选项。用户的功能选项有哪些?如何在选项之间进行挑选?
8. 运行时间。在指定的配置下,解决特定规模问题所需要的时间?
9. 精度和校验。期望结果的精确程度?如何进行精度的检测?

由于它包含了和软件相关的基本决策,所以这份文档的绝大部分需要在程序编制之前书写。

□验证程序。
还必须附带一些程序正确运行的证明,即测试用例。
1. 针对遇到的大多数常规数据和程序主要功能进行测试的用例。它们是测试用例的主要组成部分。
2. 数量相对较少的合法数据测试用例,对输入数据范围边界进行检查,确保最大可能值、最小可能值和其他有效特殊数据可以正常工作。
3. 数量相对较少的非法数据测试用例,在边界外检查数据范围边界,确保无效的输入能有正确的数据诊断提示。

□修改程序。
修改者迫切需要一份清晰明了的概述,不过这一次是关于系统的内部结构。
1. 流程图或子系统的结构图,对此以下有更详细的论述。
2. 对所用算法的完整描述,或者是对文档中类似描述的引用。
3. 对所有文件规划的解释。
4. 数据流的概要描述——从磁盘或者磁带中,获取数据或程序处理的序列——以及在每个处理过程完成的操作。
5. 初始设计中,对已预见修改的讨论;特性、功能回调的位置以及出口;原作者对可能会扩充的地方以及可能处理方案的一些意见。另外,对隐藏缺陷的观察也同样很有价值。

★流程图
 程序图是被吹得最过分的一种程序文档。事实上很多程序甚至不需要流程图,很少有程序需要一页纸以上的流程图。一页纸的流程图,成为表达程序结构、阶段或步骤的一种非常基本的图示。 
 逐一记录的详细流程图过时而且令人生厌,它只适合启蒙初学者的算法思维。
  现实中,流程图被鼓吹的程度远大于他们的实际作用。从来没有看到过一个有经验的编程人员,在开始编写程序之前,会例行公事地绘制详尽的流程图。流程图总是事后被补上。在程序中包括流程图显然是一种笨拙但不是不可以的做法。

★自文档化(self-documenting)的程序
数据处理的基本原理告诉我们,试图把信息放在不同的文件中,并努力维持它们之间的同步,是一种非常费力不讨好的事情。更合理的方法是:每个数据项包含两个文件都需要的所有信息,采用指定的键值来区别,并把它们组合到一个文件中。

把文档整合到源代码。这对正确维护是直接有力的推动,保证编程用户能方便、即时地得到文档资料。这种程序被称为自文档化。
文档是我们以及前人都不曾成功背负的重担。作为基本目标,我们必须试图把它的负担降到最小。

1、标签、声明语句、符号名称均可以作为工具,用来向读者表达尽可能多的意思。
2、用空格和一致的格式提高程序的可读性,表现从属和嵌套关系。
3、以段落注释的形式,向程序中插入必要的记叙性文字。

自文档化方法:对空间和格式要求更为严格,这一点的应用可能会受限;而命名和结构化声明显然可以利用起来,在这方面,宏可以起到很大的帮助;另外,段落注释的广泛使用在任何语言中都是一个很棒的实践。
自文档化方法激发了高级语言的使用,特别是用于在线系统的高级语言——无论是对批处理还是交互式,它都表现出最强的功效和应用的理由。因此从各方面而言,无论是从经济还是从以人为本的角度来说,他们的应用都是非常合情合理的。
 

没有银弹-软件工程中的根本和次要问题
(No Silver Bullet – Essence and Accident in Software Engineering)

没有任何技术或管理上的进展,能够独立地许诺十年内使生产率,可靠性或简洁性获得数量级上的进步。
★摘要
软件任务中的必要活动:那些和构造异常复杂的抽象概念结构有关的部分。
软件任务中的次要任务:使用编程语言表达这些抽象实体,在空间和时间限制内将它们映射成机器语言。
软件生产率在近年内取得的巨大进步来自对后天障碍的突破,例如硬件的限制,笨拙的编程语言,机器时间的缺乏等等。
软件工程师在次要任务上花费了多少时间和精力?除非它占了所有工作的9/10,否则即使全部次要任务的时间缩减到零,也不会给生产率带来数量级上的提高。
1、仔细地进行市场调研,避免开发已上市的产品
2、在获取和制订软件需求时,将快速原型开发作为迭代计划的一部分。
3、有机地更新软件,随着系统的运行、使用和测试,逐渐添加越来越多的功能。
4、不断挑选和培养杰出的概念设计人员。

★介绍
常常看似简单明了的东西,却有可能变成一个落后进度、超出预算、存在大量缺陷的怪物。因此我们听到寻求银弹就是寻求一种可以使软件成本像计算机硬件成本一样降低的尚方宝剑。
没有任何技术或管理上的进展,能够独立地许诺在生产率、可靠性或简洁性上取得数量级的提高。


★是否一定那么困难呢?——根本困难
不仅仅是在目力所能及的范围内,没有发现银弹,而且软件的特征本身也导致了不大可能有任何的发明创新。能够像计算机硬件工业中的微电子器件,晶体管,大规模集成一样。提高软件的生产率,可靠性和简洁程度。我们甚至不能期望每两年有一倍的增长。
软件开发中困难的部分是规格化、设计和测试这些概念上的结构,而不是对概念进行表达和对实现逼真程度进行验证。所以软件开发总是非常困难的,天生就没有银弹。
现代软件系统中有这些无法规避的内在特性:复杂度一致性可变性不可见性

□复杂度
软件的复杂度是必要属性,不是次要因素。因此,抽掉复杂度的软件实体描述常常也去掉了一些本质属性。
由于复杂度,团队成员之间的沟通非常困难,导致了产品瑕疵、成本超支和进度延迟;由于复杂度,函数调用变得困难,导致程序难以使用;由于结构性复杂度,程序难以在不产生副作用的情况下用新函数扩充。由于复杂度,造成很多安全机制状态上的不可见性。
复杂度不仅仅导致技术上的困难,还引发了很多管理上的问题。它使全面理解问题变得困难,从而妨碍了概念上的完整性。

□一致性
很多复杂性来自保持与其他接口的一致,对软件的任何再设计,都无法简化这些复杂特性。

□可变性
软件实体经常会遭受到持续的变更压力。
当人们发现软件很有用时,会在原有应用范围的边界,或者在超越边界的情况下使用软件。功能扩展的压力主要来自那些喜欢基本功能,又对软件提出了很多新用法的用户们。
软件一定是在某种计算机硬件平台上开发,成功软件的生命期通常比当初的计算机硬件平台要长
软件必须与各种新生事物保持一致。

□不可见性
软件是不可见的和无法可视化的。
软件仍然保持着无法可视化的固有特性,从而剥夺了一些具有强大功能的概念工具的构造思路。这种缺憾不仅限制了个人的设计过程,也严重地阻碍了相互之间的交流。

★以往解决次要困难的一些突破
□高级语言

软件生产率、可靠性和简洁性上最有力的突破是使用高级语言编程。高级语言最可能实现的是提供所有编程人员在抽象程序中能想到的要素

□分时
大多数观察者相信分时提高了程序员的生产率和产品的质量,尽管它带来的进步不如高级语言。
分时解决了完全不同的困难,分时保证了及时性,从而使我们能维持对复杂程度的一个总体把握。
批处理编程的较长周转时间意味着不可避免会遗忘一些细枝末节。
分时所起作用也非常有限。主要效果是缩短了系统的响应时间。随着它接近于零,到达人类可以辨识的基本能力所获得的好处就接近于无了。

□统一编程环境
主要通过提供集成库、统一文件格式、管道和过滤器,解决了共同使用程序的次要困难。
这样概念性结构理论上的相互调用,提供输入和相互使用,在现实中可以非常容易地实现。
环境开发是当今软件工程研究的主要题目。

★银弹的希望
□Ada和其他高级编程语言
□面向对象编程

不过,这些提高仅仅能消除所有设计表达上的次要困难。软件的内在问题是设计的复杂度。
不必要的低层次类型说明占据了软件产品设计90%,面向对象编程才能带来数量级上的提高。对面向对象编程这颗银弹,我深表怀疑。


□人工智能
很多人期望人工智能上的进展可以给软件生产率和质量带来数量级上的增长。但我不这样认为。


□专家系统
拥有一个良好可用的推测引擎,那么事实上它就可以减少测试用例设计的总体工作量,以及帮助整个软件生命周期的维护,修改和测试。构建专家系统的必要前提条件是拥有专家。
人工智能领域最先进的,被最大范围使用的部分,是开发专家系统的技术。
专家系统最强有力的贡献是给缺乏经验的开发人员提供服务,用最优秀开发者的经验和知识积累为他们提供了指导。


□“自动”编程
自动编程总是成为一种热情,使用现在并不可用的更高级语言编程的热情
1.问题通过相对较少的参数迅速地描述出特征。
2.存在很多已知的解决方案,提供了可供选择的库。
3.在给定问题参数的前提下,大量广泛的分析为选择具体的解决技术提供了清晰的规则。

□图形化编程
流程图是一种非常差劲软件结构表达方法。流程图已经成为完全不必要的设计工具。
软件非常难以可视化。即使用图形表达出了流程图、变量范围嵌套情况、变量交叉引用、数据流、层次化数据结构等等,也只是表达了某个方面

□程序验证
现代编程的许多工作是测试和修复bug。
程序验证不意味着零缺陷的程序。

□环境和工具
它能带来软件生产率和可靠性上的一些提高。但是,由于它自身的特性,目前它的回报很有限

□工作站
随着工作站的处理能力和内存容量的稳固和快速提高,不过一旦机器运算速度提高十倍,那么程序开发人员的思考活动将成为日常工作的主要活动。实际上,这已经是现在的情况。

★针对概念上根本问题的颇具前途的方法
虽然现在软件上没有技术上的突破能够预示我们可以取得像在硬件领域上一样的进展,但在现实的软件领域中既有大量优秀的工作,也有不引人注意的平稳进步。
所有针对软件开发过程中次要困难的技术工作基本上能表达成以下的生产率公式:
任务时间 = Σ(频率)i×(时间)i
如果和我所认为的一样,工作的创造性部分占据了大部分时间,那么那些仅仅是表达概念的活动并不能在很大程度上影响生产率

□购买和自行开发
构建软件最可能的彻底解决方案是不开发任何软件。以上提到的任何软件,购买都要比重新开发要低廉一些。
软件成本一直是开发的成本,而不是复制的成本。所以,即使只在少数使用者之间实现共享,也能在很大程度上减少成本。
另一种看法是使用软件系统的N个拷贝,将会使开发人员的生产率有效地提高N倍。这是一个领域和行业范围的提高。

□需求精炼和快速原型
需求工作对系统的影响比其他任何一个部分的失误都大,当然纠正需求的困难也比其他任何一个部分要大。
软件开发人员为客户所承担的最重要的职能是不断重复地抽取和细化产品的需求。事实上,客户不知道他们自己需要什么。他们通常不知道哪些问题是必须回答的。

□增量开发——增长,而非搭建系统
增量化开发使逆向跟踪很方便,并非常容易进行原型开发。每一项新增功能,以及针对更加复杂数据或情况的新模块,从已经规划的系统中有机地增长。

□卓越的设计人员
如何提高软件行业的核心,一如既往的是——人员。
低劣设计和良好设计之间的区别可能在于设计方法中的完善性,而良好设计和卓越设计之间的区别肯定不是如此。
卓越设计来自卓越的设计人员。软件开发是一个创造性的过程.完备的方法学可以培养和释放创造性地思维,但它无法孕育或激发创造性的过程。卓越和一般之间的差异接近于一个数量级。
软件开发是一个创造性的过程。完备的方法学可以培养和释放创造性的思维,但它无法孕育或激发创造性的过程
尽管很多杰出、实用的软件系统是由很多人共同设计开发,但是那些激动人心、拥有广大热情爱好者的产品往往是一个或者少数伟大设计师们的思想。
尽管公司可能缺少良好的管理人员,但决不会比良好设计人员的需求更加迫切,而卓越的管理人员和设计人员都是非常缺乏的。

1.尽可能早地、有系统地识别顶级的设计人员。最好的通常不是那些最有经验的人员。
2.为设计人员指派一位职业导师,负责他们技术方面的成长,仔细地为他们规划职业生涯。
3.为每个方面制订和维护一份职业计划,包括与设计大师的、经过仔细挑选的学习过程、正式的高级教育和以及短期的课程——所有这些都穿插在设计和技术领导能力的培养安排中。
4.为成长中的设计人员提供相互交流和学习的机会。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

进击的横打

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值