人月神话--没有银弹-软件工程中的根本和次要问题
-
- 序
- 没有任何技术或管理上的进展,能够独立地许诺十年内使生产率、可靠性或简洁性获得数量 级上的进步。
- 摘要
- 对于和构造异常复杂的抽 象概念结构有关的部分,作者建议
- 1.仔细地进行市场调研,避免开发已上市的产品。
- 2.在获取和制订软件需求时,将快速原型开发作为迭代计划的一部分。
- 3.有机地更新软件,随着系统的运行、使用和测试,逐渐添加越来越多的功能。
- 4.不断挑选和培养杰出的概念设计人员。
- 介绍
- 我们看看近十年来的情况,没有银弹的踪迹。没有任何技术或管理上的进展, 能够独立地许诺在生产率、可靠性或简洁性上取得数量级的提高。
- 解决管理灾难的第一步是将大块的“巨无霸理论”替换成“微生物理论”,它的每一步 ——希望的诞生,本身就是对一蹴而就型解决方案的冲击。它告诉工作者进步是逐步取得的, 伴随着辛勤的劳动,对规范化过程应进行持续不懈的努力。
- 是否一定那么困难呢?——根本困难
- 软件的特性本身也导致了不大可 能有任何的发明创新——能够像计算机硬件工业中的微电子器件、晶体管、大规模集成一样 ——提高软件的生产率、可靠性和简洁程度。
- 首先,计算机硬件发 展得太快。
- 其次,两种困难,根本的——软件特性中固有的困难,次要的——出现在目前生产上的, 但并非那些与生俱来的困难。
- 一个相互牵制关联的概念结构,是软件实体必不可少的部分,它包括:数据集合、数 据条目之间的关系、算法、功能调用等等。
- 我认为软件开发中困难的部分是规格化、设计和测试这些概念上的结构,而不是对概 念进行表达和对实现逼真程度进行验证
- 让我们来考虑现代软件系统中这些无法规避的内在特性(根本的困难):复杂度、一致性、可变性和 不可见性。
- 复杂度
- 软件的复杂度是必要属性,不是次要因素。
- 一致性
- 很多复杂性来自保持与其他接口的一致, 对软件的任何再设计,都无法简化这些复杂特性。
- 可变性
- 软件实体经常会遭受到持续的变更压力。
- 所有成功的软件都会发生变更。
- 当人们发现软件很 有用时,会在原有应用范围的边界,或者在超越边界的情况下使用软件。
- 功能扩展的压力主 要来自那些喜欢基本功能,又对软件提出了很多新用法的用户们。
- 不可见性
- 软件是不可见的和无法可视化的。
- 这些图形可能描绘控制流 程、数据流、依赖关系、时间序列、名字空间的相互关系等等。它们通常不是有较少层次的 扁平结构。实际上,在上述结构上建立概念控制的一种方法是强制将关联分割,直到可以层 次化一个或多个图形
- 除去软件结构上的限制和简化方面的进展,软件仍然保持着无法可视化的固有特性, 从而剥夺了一些具有强大功能的概念工具的构造思路。这种缺憾不仅限制了个人的设计过 程,也严重地阻碍了相互之间的交流
- 以往解决次要困难的一些突破
- 高级语言
- 减轻了一些次要的软件复杂度。
- 高级语言最可能实现的是提供所有编程人员在抽象程序中能想到的要素。
- 然而,对于较少使用那些复杂深奥语言要素的用户,高级语言在某种程度上增加而不 是减少了脑力劳动上的负担
- 分时
- 分时提高了程序员的生产率和产品的质量
- 分时保证了及时性,从而使我们能维持对复杂程度的一 个总体把握。
- 较长的周转时间和机器语言的复杂度一样,是软件开发过程的次要困难,而不是本质 困难。
- 分时所起作用也非常有限。主要效果是缩短了系统的响应时间。随着它接近于零,到 达人类可以辨识的基本能力——大概100 毫秒时,所获得的好处就接近于无了
- 统一编程环境
- 它们主要通过提供集成库、统一文件格式、管道和过滤器,解决了共同使用程序的次 要困难
- 银弹的希望
- 高级编程语言
- 面向对象编程
- 必须仔细地区别两个不同的概念:抽象数据类型和层次化类型,后者也被称为类(class)
- 抽象数据类型的概念是指对象 类型应该通过一个名称、一系列合适的值和操作来定义,而不是理应被隐藏的存储结构。
- 层次化类型,是允许定义可以被后续子类型精化的通用接口
- 它们都是解决了高级别的次要困难和允许采用较高层次的表现形式来表达 设计。
- 不过,这些提高仅仅能消除所有设计表达上的次要困难。软件的内在问题是设计的复 杂度,上述方法并没有对它有任何的促进。
- 人工智能
- 专家系统
- “自动”编程
- 大多数情况下所给出的技术说明本质上是问题的解决方法,而不是问题自身。
- 图形化编程
- 流程图是一种非常差劲软件结构表达方法
- 现在的屏幕非常小,像素级别,无法同时表现软件图形的所有正式、详细的范 围和细节。
- 更加基本的是,软件非常难以可视化。
- 程序验证
- 这项技术并不能保证节约劳动力
- 程序验证不意味着零缺陷的程序
- 完美的程序验证只能建立满足技术说明的程序
- 环境和工具
- 人 们的本能反应是首先着手解决高回报的问题:层次化文件系统,统一文件格式以获得一致的 编程接口和通用工具等。
- 它们 最有希望实现的是消除语法错误和简单的语义错误。
- 工作站
- 程序开发人员的思考活动将成为日 常工作的主要活动。
- 针对概念上根本问题的颇具前途的方法
- 所有针对软件开发过程中次要困难的技术工作基本上能表达成以下的生产率公式: 任务时间 = ∑(频率)×(时间)
- 工作的创造性部分占据了大部分时间,那么那些仅仅是表达 概念的活动并不能在很大程度上影响生产率
- 购买和自行开发
- 构建软件最可能的彻底解决方案是不开发任何软件。
- 软件成本一直是开 发的成本,而不是复制的成本。
- 另一种看法是使用软件系统的n 个拷贝,将会使开发人员的生产率有效地提高 n 倍。
- 当然,关键的问题还是可用性。
- 用户不会在 工资系统、物流控制、帐务处理等系统中使用商用软件包。需求往往过于专业,不同情况之 间的差别太大。
- 重大的变化在于计算机硬件/ 软件成本比率
- 需求精炼和快速原型
- 需求工作对系统的影响比其他 任何一个部分的失误都大,当然纠正需求的困难也比其他任何一个部分要大
- 软件开发人员为客户所承担的最重要的职能是不断重复地抽取和细化产品的需 求。
- 在尝试和开发一些客户定制的系统之前,即 使他们和软件工程师一起工作,想要完整、精确、正确地抽取现代软件产品的需求——这, 实际上也是不可能的。
- 因此,现在的技术中最有希望的,并且解决了软件的根本而非次要问题的技术,是开 发作为迭代需求过程的一部分——快速原型化系统的方法和工具
- 软件系统的快速原型对重要的系统界面进行模拟,并演示待开发系统的主要功能
- 原型的目的是明确实际的概念结构,从而 客户可以测试一致性和可用性。
- 增量开发——增长,而非搭建系统。
- 建议所有软件系统都应该 以增量的方式开发
- 即,首先系统应该能够运行,即使未完成任何有用功能,只能正确调 用一系列伪子系统。接着,系统一点一点被充实,子系统轮流被开发,或者是在更低的层次 调用程序、模块、子系统的占位符(伪程序)等
- 这种方法迫切地要求自顶向下设计, 因为它本身是一种自顶向下增长的软件。增量化开发使逆向跟踪很方便,并非常容易进行原 型开发。每一项新增功能,以及针对更加复杂数据或情况的新模块,从已经规划的系统中有 机地增长。
- 这种开发模式对士气的推动是令人震惊的。
- 卓越的设计人员。
- 关键的问题是如何提高软件行业的核心,一如既往的是——人员。
- 低劣设计和良好设计之间的 区别可能在于设计方法中的完善性,而良好设计和卓越设计之间的区别肯定不是如此。
- 软件开发是一个创造性的过程。完备的方法学可以培养和释放创 造性的思维,但它无法孕育或激发创造性的过程。
- 一个接一个的研究显示,非常卓越的设 计者产生的成果更快、更小、更简单、更优雅,实现的代价更少。卓越和一般之间的差异接 近于一个数量级。
- 我们可以着手 的最重要工作是寻求培养卓越设计人员的途径
- 如何培养杰出的设计人员
- 尽可能早地、有系统地识别顶级的设计人员。最好的通常不是那些最有经验的人员
- 为设计人员指派一位职业导师,负责他们技术方面的成长,仔细地为他们规划职业 生涯。
- 为每个方面制订和维护一份职业计划
- 为成长中的设计人员提供相互交流和学习的机会
blog comments powered by Disqus