传统软件工程原理
传统软件工程原则
对“老式”工程软件有很多描述。软件行业在多年的软件开发过程中积累了许多经验教训,并建立了许多原则。本部分通过描述对当今软件工程原则的一种视角,介绍了贯穿本书其余部分探讨的基本思想。我选择了一篇题为“软件工程十五原则”[Davis,1994]的小论文作为基准。这篇论文后来扩展成一本书[Davis,1995],列出了201个原则。尽管标题如此,但这篇文章概述了最重要的30个原则,它也是对软件行业常识的最佳描述之一。虽然我同意其中的大部分内容,但我认为其中一些内容已经过时。接下来,以斜体字显示的是戴维斯最重要的30个原则。对于每个前提,我都会讨论本书后面介绍的观点是否支持或与之矛盾。这里我提出了一些论点,直到后续章节才会得到充分的支持。
优先考虑质量。必须对其进行量化,并制定措施以鼓励实现。
为手头的项目定义合适的质量至关重要,但在项目开始时很难做到。因此,现代流程框架的目标是在生命周期的早期尽可能地理解特性、质量、成本和进度之间的权衡。除非获得这些知识,否则无法指定或控制质量的实现。
创建高质量软件是可行的。让客户参与、原型设计、简化设计、执行检查和招聘最优秀的人员都是提高质量的行之有效的方法。该原则在大多数方面都与其他原则重叠。
尽快向消费者提供商品。无论您在需求阶段多么努力地弄清楚消费者想要什么,唯一能找到他们想要什么的方法就是向他们提供产品,让他们试用。
这是现代流程结构的一个关键方面,必须有很多方法来保持客户在整个生命周期中的参与。根据领域的不同,这些技术可能包括演示原型、基于演示的里程碑和 alpha/beta 版本。
在定义标准之前,先弄清楚问题是什么。大多数工程师在遇到他们认为是问题的事情时,都会急于提出解决方案。在尝试解决问题之前,请确保您已经考虑了所有选择,并且没有被显而易见的解决方案所迷惑。
该原则指出了传统需求规范方法的问题。随着解决方案的发展,问题的参数变得更加明显。现代流程框架共同努力开发问题和解决方案,直到对问题有足够的了解才能投入全面生产。
考虑多种设计方案。在您就标准达成一致后,您需要查看许多设计和方法。您应该避免仅因为在需求规范中提到了“架构”而使用它。
这个原则似乎在两个方面都根植于瀑布式思维:(1)需求优先,而不是架构之后。(2)需求定义包括架构。虽然现代流程鼓励评估设计方案,但这些活动与需求定义同时发生,并且需求和架构的符号和工件是明确分开的。
使用合适的流程模型。根据公司文化、冒险意愿、应用领域、需求的波动性和需求的充分理解程度,每个项目都必须选择最适合该项目的流程。
没有放之四海而皆准的流程。我使用“流程框架”一词来描述一类灵活的流程,而不是一个单一的僵化实例。
对不同阶段使用多种语言。许多人认为,最佳开发流程是在整个生命周期中使用相同符号的流程,这是因为我们行业对复杂问题的简单答案有着无法满足的需求。如果Ada不是所有这些阶段的最佳语言,为什么软件工程师要将Ada用于需求、设计和代码呢?
这是一个需要记住的关键思想。第 6 章描述了流程的原始工件,并给出了可接受的安排和推荐的语言/符号。
将认知距离最小化。为了减少认知距离,软件的结构应尽可能接近现实世界的结构。
面向对象方法、基于组件的开发和可视化建模的发展都受到了这一概念的推动。
优先考虑技术而非工具。一个危险的、缺乏纪律的软件工程师会变成一个拥有工具但仍然缺乏纪律的软件工程师。虽然这个观点是正确的,但它忽略了两个关键点:(1)一个纪律严明的软件工程师拥有好的工具,其效率要高于一个没有好工具的纪律严明的软件专家。(2)自动化是促进、标准化和提供优良方法的最有效策略之一。
在尝试加速之前先把它做好。使功能程序运行得更快比使快速程序工作要容易得多。在早期编码过程中,不要担心优化。
这是一个很好的说法。一些软件专家误解了它,如下所示:“软件系统中早期的性能问题是下游危险的明确标志。”在我知道的每个成功的、非平凡的软件项目中,性能问题都出现在生命周期的早期。我想说的是,在我所知道的几乎所有不成熟的架构(特别是大型架构)的最初可执行迭代中,都会出现性能问题。了解各种性能权衡需要尽早运行(工作)。仅仅通过检查来获得这种理解太困难了。
检查代码。测试比检查详细设计和代码更能有效地检测缺陷。对于除最简单的软件系统之外的所有系统,该原则的重要性都被夸大了。得益于当今的硬件资源、编程语言和自动化环境,可以在整个生命周期中高效地进行自动化分析和测试。在当今的迭代开发中,持续的和自动化的生命周期测试是必不可少的。
在一般性的、无目标的检查(与关注已知问题的检查相反)中,很少发现架构缺陷和全局设计缺陷。这并不是说所有检查都没有价值。当明智地使用并关注已知问题时,检查在解决问题方面非常有效。但是,鉴于该行业的默认方法是过度检查,因此该指南不应属于最重要的 15 个指南。
有效的管理比优越的技术更重要。糟糕的管理不会因为最好的技术而得到补偿,而一位称职的管理者即使资源很少也能取得巨大的成就。良好的管理激励员工尽最大努力工作,但没有普遍接受的“正确”管理方法。
凭借少量预算和时间表,一个强大且管理良好的团队可以做出非凡的事情。另一方面,优秀的管理和低素质的团队是相互排斥的,因为一位优秀的经理会吸引、配置和留住一个高质量的团队。
人是取得成功最重要的因素。拥有必要经验、才能和培训的高素质人员的重要性怎么强调都不为过。在缺乏工具、语言和流程的情况下,合适的人员也能取得成功。使用错误的工具、语言和流程的错误人员几乎肯定会失败。这个原则在优先级列表中的位置太低了。
谨慎行事。 仅仅因为其他人都在这样做并不意味着它也适合你。它可能是正确的,但你必须仔细考虑它在你这种情况下的适用性。面向对象、度量、复用、流程优化、CASE、原型设计——所有这些技术都有可能提高质量、节省成本并提升用户满意度。但这些方法的承诺往往被夸大,其优势远非确定或普遍。
这尤其在快节奏的行业中是明智的建议,在快节奏的行业中,技术潮流和进步可能难以识别。在平衡功能、价格和截止日期方面,最新的技术并不一定是最优选择。
对你的行为负责。当桥梁倒塌时,我们会问:“工程师出了什么问题?” 即使软件失败,我们也很少会这样问。事实上,在每一个工程领域,最先进的方法都可能导致糟糕的设计,而最原始的方法却可能产生优秀的解决方案。
这是对第14条的绝佳补充。要取得成功,你需要的不仅仅是好的技术、工具和组件。你还需要优秀的人才、有效的管理和一种学习型文化,这种文化强调持续发展,即使会遇到频繁且不可避免的中间失败。
认识到客户的首要任务。 如果只有10%的功能按时交付,而90%的功能延迟交付,客户也可能接受。理解客户的优先级至关重要,但这必须放在其他利益相关者利益的背景下。“客户永远是对的”这一信念可能导致的资金浪费比任何其他信念都多。客户经常是错的,尤其是在政府合同领域,但更广泛地说,每当客户与系统集成商签订合同时都会出现这种情况。
他们看得越多,需求越多。 你提供的功能(或性能)越多,用户就越想要更多功能(或性能)。这种说法是对的,但这意味着你永远不应该向用户展示任何东西。“用户看得越多,理解得越好”,这句话更贴切。并非所有投资者都只被利润驱动。他们知道自己的资源有限,也知道开发人员面临的限制。
必须同步利益相关者的期望,因此展示中间成果是一项高度可见的活动。在现代流程中,软件项目经理需要客观的事实来证明不可避免的变更请求是合理的,并平衡成本、功能和风险。
制定一个丢弃一个的计划。 产品是否完全是新的,这是最重要的关键成功因素之一。新的应用程序、系统、接口或算法很少在第一次使用时就获得成功。
你应该不打算丢弃一个。相反,你应该旨在将产品从早期原型发展到完全功能的基线。如果你必须丢弃它,那也没关系,但不要计划这样做。过去,对于需要100%定制、尖端软件开发的项目来说,这可能是明智的建议。如今的软件系统(至少包括操作系统、DBMS、GUI、网络和中间件)中的许多组件已经存在,第一次开发的许多内容都可以重复使用。
创建灵活的设计。 你使用的架构、组件和规范方法必须能够适应变化。这是一个简单的陈述,但已被证明非常难以实现。从本质上讲,这意味着我们必须预测未来,并构建一个框架来接受尚未完全定义的变化。尽管如此,我完全支持这个想法,因为它对成功至关重要。虽然不可能准确预测未来,但尝试预测系统生命周期中可能发生的变更类型,是一项有益的风险管理工作,也是成功软件项目的共同主题。
设计只有在有文档支持的情况下才算完成。 我经常听到软件开发人员说:“我已经完成了设计。剩下的只是文书工作。”
这个概念也源于传统的文档驱动方法,在这种方法中,文档与程序分开维护。使用可视化建模和高级编程语言,为定义软件设计而维护单独的文档通常是低效的。如果高级架构文档编写清晰简洁,它们可能非常有用,但设计符号、源代码和测试基线是工程团队使用的主要工件。为了更好地利用当今的技术进步,我会将这种方法修改如下:“大多数软件工件应该是自文档化的。”