常规软件工程原理

常规软件工程原理

有几种“老派”工程软件的描述。在多年的软件开发过程中,软件行业吸取了很多教训,建立了许多原则。这一部分通过描述当今软件工程原则的一个观点,介绍了本书其余部分所探讨的基本思想。一篇题为“软件工程的十五条原则”[Davis,1994] 的小论文是我选择的基准。这篇论文随后被扩展成一本书 [Davis, 1995],其中列出了 201 条原则。尽管它的标题,这篇文章概述了前 30 条原则,它与软件行业的任何常识一样出色。虽然我同意其中的大部分内容,但我觉得其中一些已经过时了。紧随其后的斜体字是戴维斯的前 30 条原则。对于每个前提,我都会讨论本书后面提出的观点是支持还是反对它。我在这里提出了一些声明,直到后续章节才得到完全支持。

  • 质量优先。必须对其进行量化并采取措施来鼓励其实现。

    定义适合手头项目的质量至关重要,但在项目开始时很难做到。因此,现代流程框架旨在在生命周期中尽早掌握特性、质量、成本和进度之间的权衡。除非获得这种知识,否则无法指定或控制质量的实现。

  • 创建高质量的软件是可行的。让客户参与、原型制作、简化设计、执行检查和招聘最优秀的人员都是提高质量的行之有效的方法。这一原则在大多数方面与其他原则重叠。

  • 尽快为消费者提供商品。无论您在需求阶段如何努力弄清楚消费者想要什么,找出他们想要什么的唯一方法就是向他们提供产品并让他们玩弄它。

    这是现代流程结构的一个关键方面,必须有许多方法来让客户参与整个生命周期。这些技术可能包括演示原型、基于演示的里程碑和 alpha/beta 版本,具体取决于领域。

  • 在定义标准之前,先弄清楚问题是什么。大多数工程师在遇到他们认为存在的问题时会急于提出补救措施。在尝试解决问题之前,请确保您已经考虑了所有选项并且没有被显而易见的解决方案所迷惑。

    该原则确定了传统需求规范方法的问题。随着解决方案的发展,问题的参数变得更加明显。一个现代的流程框架共同开发问题和解决方案,直到问题被充分理解以致力于全面生产。

  • 考虑几个设计选项。 在您就标准达成一致后,您需要查看许多设计和方法。您应该避免使用“架构”,因为它在需求规范中被提及。

    这个想法似乎以两种方式植根于瀑布思维:(1)需求在前,而不是架构在后。(2) 需求定义包括架构。虽然当代流程鼓励对设计备选方案的评估,但这些活动与需求定义同时发生,并且需求和架构的符号和工件是明确分开的。

  • 使用合适的流程模型。根据公司文化、承担风险的意愿、应用领域、需求的波动性以及对需求的充分理解程度,每个项目都必须选择最适合该项目的流程。

    没有通用程序这样的东西。我使用术语流程框架来描述灵活的流程类,而不是单一的刚性实例。

  • 在各个阶段使用多种语言。许多人表示,最佳开发过程是在整个生命周期中使用相同符号的过程,因为我们的行业对复杂问题的简单答案永无止境。如果 Ada 不是所有这些阶段的最佳语言,为什么软件工程师要使用 Ada 来处理需求、设计和代码?

    这是一个需要记住的关键想法。该过程的原始工件在第 6 章中以可接受的安排和推荐的语言/符号进行了描述。

  • 将智力距离保持在最低限度。为了减少认知距离,软件的结构应该尽可能接近现实世界的结构。

    面向对象方法、基于组件的开发和可视化建模的发展都是由这个概念推动的。

  • 将技术置于工具之上。 一个危险的、没有纪律的软件工程师变成了一个没有纪律的软件工程师,有一个工具。虽然这个想法是合理的,但它忽略了两个关键点:(1) 拥有良好工具的训练有素的软件工程师将胜过没有良好工具的训练有素的软件专家。(2) 自动化是促进、标准化和提供卓越方法的最有效策略之一。

  • 在尝试加快速度之前先做好准备。使函数式程序运行得更快比使程序快速运行要容易得多。在早期编码期间,不要担心优化。

    这是一个极好的声明。一些软件专家对其进行了如下曲解:“软件系统中的早期性能困难是下游危险的明确标志。” 我所知道的每个成功的、重要的软件项目的生命周期早期都会出现性能问题。我想说的是,在它们最初的可执行迭代中,几乎所有不成熟的架构(尤其是大型架构)都会遇到性能问题。了解各种性能权衡需要尽早运行(运行)某些东西。通过考试获得这种理解实在是太难了。

  • 检查代码。与检查详细设计和代码相比,测试是一种更好的缺陷检测技术。除了最简单的软件系统,这个想法的重要性被夸大了。得益于当今的硬件资源、编程语言和自动化环境,可以在整个生命周期内高效地进行自动化分析和测试。在当今的迭代开发中,连续和自动化的生命周期测试是必须的。

    在一般的、无方向的检查(而不是专注于公认问题的检查)中,很少发现架构缺陷和全局设计妥协。这并不是说所有检查都毫无价值。如果明智地使用并专注于已知问题,检查在解决问题方面非常成功。然而,鉴于行业的默认做法是过度检查,该指南不应进入前 15 名。

  • 拥有有效的管理比拥有卓越的技术更重要。最伟大的技术不会补偿糟糕的管理,而称职的经理即使资源很少也可以取得巨大的成果。良好的管理激励员工发挥最佳表现,但没有普遍接受的“正确”管理方法。

    在预算和时间表很少的情况下,一个强大、管理良好的团队可能会做出非凡的事情。另一方面,优秀的管理和低素质的团队是相互排斥的,因为一个好的管理者会吸引、配置和留住一个高素质的团队。

  • 人是取得成功的最重要因素。具有必要经验、才能和培训的高素质人才的重要性不言而喻。如果工具、语言和流程不足,合适的人就会成功。错误的人,使用错误的工具、语言和流程,几乎肯定会失败。这个想法在优先级列表中太低了。

  • 谨慎行事。仅仅因为其他人都在这样做并不意味着它适合你。它可能是正确的,但您必须仔细考虑它是否适合您的情况。面向对象、测量、重用、流程优化、CASE、原型设计——所有这些技术都有可能提高质量、节省成本和提高用户满意度。此类程序的承诺经常被夸大,其优势远非确定或普遍。

    这是一个合理的建议,尤其是在快节奏的行业中,技术潮流和进步很难识别。在平衡功能、定价和截止日期方面,最新的技术不一定是最佳选择。

    为你的行为负责。当一座桥倒塌时,我们想知道,“工程师们出了什么问题?” 即使软件出现故障,我们也很少询问这个问题。事实是,在每个工程学科中,最先进的程序可能会导致可怕的设计,而最原始的方法可能会导致可爱的解决方案。

    这是第 14 条的精彩后续。要成功,您需要的不仅仅是好的技术、工具和组件。它还需要强大的人才、有效的管理和学习文化,尽管中间失败频繁且不可避免,但强调向前发展。

  • 认识到客户的首要任务。如果只有 10% 的功能按时交付,客户会接受延迟提供的 90% 的功能是可行的。了解客户的优先事项至关重要,但仅限于其他利益相关者的利益。“客户永远是对的”的信念可能导致浪费的钱比其他任何钱都多。客户经常犯错,尤其是在政府合同领域,但更广泛的是,每当客户与系统集成商签订合同时。

  • 当他们看到更多时,他们需要更多。您提供的功能(或性能)越多,用户所需的功能(或性能)就越多。这种方法是正确的,但是,它意味着您永远不应该向用户显示任何内容。“消费者看到的越多,他们理解得越好,”它应该读到。并非每个投资者都只受利润驱动。他们了解自己有限的资源和开发人员面临的限制。

    利益相关者的期望必须同步,因此展示中间结果是一项高度可见的活动。软件项目经理需要客观事实来证明不可避免的变更请求的合理性,并在当代流程中保持成本、功能和风险的平衡。

  • 制定一个计划来摆脱一个。 产品是否全新是最关键的成功要素之一。新的应用程序、系统、接口或算法很少在第一次使用时就成功。

    你不应该打算丢弃一个。相反,您的目标应该是将产品从早期原型开发为功能齐全的基线。如果你不得不扔掉它,那没关系,但不要计划它。对于过去需要 100% 定制的尖端软件开发的项目,这可能是合理的建议。当今软件系统中的大部分组件(至少是操作系统、DBMS、GUI、网络和中间件)已经存在,并且第一次生成的大部分内容都可以重用。

  • 创建灵活的设计。您使用的架构、组件和规范方法必须适应变化。这是一个简单的声明,已被证明很难实施。从本质上讲,它表明我们必须预测未来并建立一个框架来接受尚未完全定义的变化。尽管如此,我完全支持这个想法,因为它对成功很重要。尽管不可能正确预测未来,但尝试预测系统生命周期中可能发生的变化类型是一项有用的风险管理练习,也是成功软件项目的共同主题。

  • 设计不是它的样子,直到它伴随着文档。我经常听到软件开发人员这样说:“我已经完成了设计。剩下的就是文书工作。”

    这个概念也植根于传统的文档驱动方法,其中文档与程序分开。为定义软件设计而维护单独的论文对于可视化建模和高级编程语言通常是无效的。如果编写得清晰和简单,高级架构论文会非常有用,但设计符号、源代码和测试基线是工程团队使用的主要工件。为了更好地利用当今的技术突破,我将改变这种方法如下:“大多数软件工件应该是自记录的。”