良好软件工程方法的基本原则

软件工程是指在创建软件产品和应用程序时使用系统工程原理。它是一门与评估用户需求、软件设计、开发、测试和维护有关的工程学科。

以下是优秀软件工程的一些基本原则 -

  • 更好的需求分析是一种基本的软件工程技术,可提供项目的全面图景。最后,对用户需求的透彻掌握可以通过生产满足消费者需求的高质量软件解决方案为消费者增加价值。

  • 所有的设计和实现都应该尽可能基本,这意味着坚持 KISS(保持简单,愚蠢)的理念。它简化了代码,从而简化了调试和维护。

  • 软件项目成功的最关键方面是在整个开发过程中保持项目的愿景。由于对项目有清晰的愿景,因此可以正确开发。

  • 许多功能都包含在软件项目中;所有功能都应使用模块化方法设计,以使开发更快更简单。由于这种模块化,功能或系统组件是独立的。

  • 抽象是关注点分离思想的一种特殊化,用于抑制复杂的事物并为客户/用户提供简单性,这意味着它只为用户提供他们需要的东西并隐藏其余的东西。

  • 行动前思考是软件工程中的必备概念,这表明在开始实现功能之前,您必须首先考虑应用程序架构,因为正确规划项目开发流程会产生更好的结果。

  • 当开发人员组合所有功能时,他或她随后可能会发现不再需要它们。因此,坚持“永不添加额外”方法至关重要,因为它只执行真正需要的内容,从而节省时间和精力。

  • 当其他开发人员在处理另一个人的代码时,他们不应该感到惊讶,也不应该花时间试图弄清楚发生了什么。因此,在关键阶段改进文档是改进软件项目的极好方法。

  • 应该遵守 Demeter 定律,因为它根据类的功能分离类并减少耦合(类之间的连接和相互依赖)。

  • 开发者应该以符合通用性原则的方式设计项目,这意味着它不应该被限制或限制在特定的案例/功能集上,而应该不受非自然约束并能够提供全面的为有特殊或一般需求的客户提供服务。

  • 一致性原则在编码风格和 GUI(图形用户界面)设计中很重要,因为一致的编码风格使代码更易于理解,而一致的 GUI 使用户更容易学习界面和程序。

  • 如果需要某些东西并且已经不碍事,永远不要花时间;相反,使用开源以您自己独特的方式来解决它。

  • 持续验证可确保软件系统满足其要求并发挥其预期功能,从而改进软件质量控制。

  • 摆脱当前的技术行业热潮 使用当前的编程方法以尽可能最新和最复杂的方式满足用户的需求至关重要。

  • 为了扩展和处理对软件应用程序不断增长的需求,应该保持软件工程的可扩展性。

  • 目的分离——关注点分离承认人类在受限环境中运作的要求。根据 GA Miller [Miller56] 的说法,人类的大脑一次只能处理大约 7 个单位的数据。一个单元是一个人已经学会将其作为一个整体来处理的单一想法或概念。尽管人类似乎具有无限的抽象能力,但抽象成为有用的工具需要时间和反复使用;也就是作为一个单位发挥作用。

    在定义数据结构组件的行为时,通常需要考虑两个因素:基本功能和数据完整性支持。当这两个关注点尽可能地分离到不同的客户端方法集时,数据结构组件通常更易于使用。如果客户文档单独解决这两个问题,客户将受益。单独考虑核心算法以及数据完整性和异常处理的更改也可能有益于实现文档和算法解释。

    出于另一个原因,关注点分离也很重要。为了提高产品的质量,软件开发人员必须处理复杂的值。我们可以从算法复杂性的研究中吸取宝贵的教训。尽管存在最大化单个可测量变量的有效方法,但需要优化许多数量的问题几乎总是 NP 完全的。虽然这没有得到证明,但大多数复杂性理论专家认为多项式时间算法不能解决 NP 完全问题。

    鉴于此,拆分不同值的处理似乎是合适的。这可以通过在整个软件开发过程中处理不同时期的各种值来实现,或者通过安排架构使得不同的组件负责获得不同的值。

    运行时效率是一个通常与其他软件值发生冲突的值的示例。因此,大多数软件工程师建议将效率视为一个独特的问题。在创建程序以满足其他要求之后,可以评估和分析运行时间以发现时间花费在哪里。如果需要,可以更新使用大部分运行时间的代码区域以减少运行时间。Ken Auer 和 Kent Beck 在 [VCK96,第 19-42 页] 中的论文“Lazy optimization: patterns for Effective smalltalk programming”详细介绍了这个概念。

  • 模块化——模块化的概念是关注点分离原则的一个子集。遵循模块化概念需要根据其功能和职责将软件分解为组件。Parnas [Parnas72] 撰写了关于模块化问题的第一篇文章之一。[WWW90] 是一篇更现代的论文,在面向对象的环境中提供了一种责任驱动的模块化技术。

  • 抽象- 关注点分离概念的特殊化是抽象原则。将软件组件的行为与其实现分离是抽象原则的要求。它需要学习从两个角度检查软件和软件组件:它们做什么以及它们如何做。

    不必要的耦合通常是由于未能将行为与实现分开造成的。例如,在递归算法中,通常会添加额外的参数以使递归起作用。之后,应使用非递归 shell 调用递归,该 shell 为附加参数提供适当的起始值。否则,调用者将面临更复杂的行为,需要指定附加参数。如果实现最终切换到非递归方法,则需要更改客户端代码。

    对于处理抽象,契约式设计是一项关键技术。Fowler 和 Scott [FS97] 概述了契约式设计的基本概念。Meyer [Meyer92a] 提供了对该方法的最全面的描述。

  • 变化预期- 计算机程序是对问题的计算机辅助解决方案。该问题发生在软件用户已知的上下文或域中。域指定了用户需要使用的数据种类,以及它们之间的连接。

    另一方面,软件工程师熟悉数据抽象技术。他们使用结构和算法而不关心数据的含义或重要性。在没有给顶点和边赋予特定含义的情况下,软件开发人员可能会根据图和图算法进行构思。

    因此,找出问题的自动化解决方案是软件工程师及其客户的学习过程。软件开发人员正在学习客户端操作的领域。他们还了解客户的价值观:什么样的数据呈现方式对客户最有价值,哪些类型的数据是关键的,需要特定的保护措施。

    客户越来越意识到软件技术可以带来的解决方案的广度。他们还学习根据满足客户需求的能力来评估潜在解决方案。

    如果要解决的问题很复杂,那么期望在短时间内找到最佳答案是不合理的。另一方面,客户需要快速响应。大多数时候,他们不愿意等到找到理想的答案。他们希望尽快得到可接受的答案;完美可以等待。程序工程师需要了解需求或软件应该如何运行,以便及时提出解决方案。变革参与的概念承认软件工程师及其客户学习过程的困难。早期应拟定初步需求,但应允许随着学习的发展对标准进行调整。

    耦合是转型的重要障碍。如果两个组件紧密连接,则更改一个组件几乎肯定需要更换另一个组件。

    内聚性对可变性有有利的影响。当需求发生变化时,内聚组件更易于重用。如果一个组件将多个作业组合到一个包中,则在进行修改时几乎肯定需要将其拆分。

  • 普遍性- 普遍性的概念与变化预期的概念有关。创建不受人为约束和限制的软件至关重要。两位数年份数字的使用是人为约束或限制的一个突出例子,它导致了“2000 年”问题:软件将在世纪之交混淆记录。尽管当时两位数的限制似乎可以接受,但优秀的软件通常会超过其预期的使用寿命。

    考虑将业务方法更改为自动化软件的客户作为通用性概念的另一个例证。他们经常试图满足广泛的需求,但他们根据现有的行为认识并表达了自己的需求。随着他们对自动化解决方案的功能有了更好的理解,他们开始认识到他们需要什么,而不是他们目前正在做什么来满足这些要求。这种差异类似于抽象差异化的概念,但其后果在软件开发过程中更早实现。

  • 小步开发- Fowler 和 Scott [FS97] 提供了对增量软件开发方法的简洁而全面的概述。这种方法涉及以微小的步骤构建软件,例如一次添加一个用例。

    使用增量软件开发方法可以更轻松地进行验证。如果您以微小的增量构建软件,则在验证时您只需要处理新引入的功能。如果发现任何错误,它们已经部分分离,从而使它们更容易纠正。

    通过精心规划的增量开发策略,还可以更轻松地处理需求的变化。为此,规划必须确定最有可能被更改的用例,并将它们放在开发过程的最后。

  • 一致性——一致性的概念承认在熟悉的环境中完成任务更简单。例如,编码风格是一种以统一方式放置代码文本的方法。这实现了两个目标。对于初学者来说,它可以更轻松地理解代码。其次,它使程序员能够自动化输入代码所需的一些能力,使他们能够专注于更关键的挑战。更高级别的一致性需要创建用于处理典型编程问题的习语。