软件实现



在本章中,我们将学习软件实现中的编程方法、文档和挑战。

结构化编程

在编码过程中,代码行不断增加,从而导致软件大小增加。渐渐地,记住程序流程变得几乎不可能。如果忘记了软件及其底层程序、文件、过程是如何构建的,那么共享、调试和修改程序就会变得非常困难。解决方法是结构化编程。它鼓励开发人员使用子程序和循环,而不是在代码中使用简单的跳转,从而使代码更清晰并提高效率。结构化编程还有助于程序员减少编码时间并正确组织代码。

结构化编程规定了程序的编码方式。结构化编程使用三个主要概念

  • 自顶向下分析 - 软件总是被设计用来执行一些合理的工作。在软件术语中,这项合理的工作被称为问题。因此,了解如何解决问题非常重要。在自顶向下分析中,问题被分解成许多小块,每个小块都具有一定的意义。每个问题都单独解决,并明确说明解决问题的方法。

  • 模块化编程 - 在编程过程中,代码被分解成更小的指令组。这些组被称为模块、子程序或子例程。模块化编程基于对自顶向下分析的理解。它不鼓励在程序中使用“goto”语句进行跳转,这往往会使程序流程难以追踪。在结构化编程中,禁止使用跳转并鼓励使用模块化格式。

  • 结构化编码 - 参考自顶向下分析,结构化编码将模块进一步细分为更小的代码单元,并按执行顺序排列。结构化编程使用控制结构来控制程序流程,而结构化编码使用控制结构以可定义的模式组织其指令。

函数式编程

函数式编程是一种编程语言风格,它使用数学函数的概念。数学中的函数在接收到相同参数时,应该始终产生相同的结果。在过程式语言中,程序的流程通过过程运行,即程序的控制权转移到被调用的过程。在控制流从一个过程转移到另一个过程时,程序会改变其状态。

在过程式编程中,当使用相同参数调用过程时,它可能会产生不同的结果,因为程序本身在调用过程中可能处于不同的状态。这是过程式编程的一个特性也是一个缺点,其中过程执行的顺序或时间变得很重要。

函数式编程提供了一种将计算作为数学函数的方式,无论程序状态如何,它都能产生结果。这使得预测程序的行为成为可能。

函数式编程使用以下概念

  • 一等函数和高阶函数 - 这些函数能够接受另一个函数作为参数,或者将其他函数作为结果返回。

  • 纯函数 - 这些函数不包含破坏性更新,也就是说,它们不影响任何I/O或内存,如果它们没有被使用,则可以很容易地删除它们而不会影响程序的其余部分。

  • 递归 - 递归是一种编程技巧,其中一个函数调用自身并在其中重复程序代码,除非某些预定义条件匹配。递归是在函数式编程中创建循环的方式。

  • 严格求值 - 这是对作为参数传递给函数的表达式的求值方法。函数式编程有两种类型的求值方法,严格(急切)或非严格(惰性)。严格求值始终在调用函数之前对表达式进行求值。非严格求值不会对表达式进行求值,除非需要。

  • λ演算 - 大多数函数式编程语言使用λ演算作为其类型系统。λ表达式通过在它们出现时对其进行求值来执行。

Common Lisp、Scala、Haskell、Erlang和F#是一些函数式编程语言的示例。

编程风格

编程风格是一套所有程序员遵循的编码规则,用于编写代码。当多个程序员在同一个软件项目上工作时,他们经常需要使用其他开发人员编写的程序代码。如果所有开发人员不遵循一些标准的编程风格来编写程序,这就会变得乏味,有时甚至是不可能的。

合适的编程风格包括使用与预期任务相关的函数和变量名、使用适当的缩进、为方便阅读者而注释代码以及代码的整体呈现。这使得程序代码易于所有人员阅读和理解,从而使调试和解决错误更容易。此外,正确的编码风格有助于简化文档和更新。

编码指南

编码风格的实践因组织、操作系统和编码语言本身而异。

以下编码元素可以在组织的编码指南中定义

  • 命名约定 - 本节定义如何命名函数、变量、常量和全局变量。

  • 缩进 - 这是在行首留出的空格,通常是2-8个空格或单个制表符。

  • 空白字符 - 通常在行尾省略。

  • 运算符 - 定义编写数学、赋值和逻辑运算符的规则。例如,赋值运算符“=”应该在其前后留有空格,如“x = 2”。

  • 控制结构 - 编写if-then-else、case-switch、while-until和for控制流语句的规则,包括单独使用和嵌套使用。

  • 行长度和换行 - 定义一行中应该有多少个字符,大多数情况下,一行有80个字符。换行定义了如果一行太长,应该如何换行。

  • 函数 - 定义如何声明和调用函数,包括带参数和不带参数的函数。

  • 变量 - 说明如何声明和定义不同数据类型的变量。

  • 注释 - 这是重要的编码组件之一,因为代码中包含的注释描述了代码的实际作用以及所有其他相关描述。本节还有助于为其他开发人员创建帮助文档。

软件文档

软件文档是软件过程的重要组成部分。编写良好的文档提供了一个强大的工具和信息库,用于了解软件过程。软件文档还提供有关如何使用产品的信息。

维护良好的文档应该包含以下文档

  • 需求文档 - 该文档作为软件设计师、开发人员和测试团队执行各自任务的关键工具。该文档包含预期软件的所有功能、非功能和行为描述。

    该文档的来源可以是先前存储的有关软件的数据、客户端已运行的软件、客户端访谈、问卷调查和研究。通常,它以电子表格或文字处理文档的形式存储在高级软件管理团队中。

    该文档作为要开发的软件的基础,主要用于验证和确认阶段。大多数测试用例都是直接从需求文档中构建的。

  • 软件设计文档 - 这些文档包含构建软件所需的所有必要信息。它包含:(a) 高级软件架构,(b) 软件设计细节,(c) 数据流图,(d) 数据库设计

    这些文档作为开发人员实现软件的存储库。尽管这些文档没有提供任何有关如何编写程序的细节,但它们提供了编码和实现所需的所有必要信息。

  • 技术文档 - 这些文档由开发人员和实际编码人员维护。这些文档作为一个整体,代表了有关代码的信息。在编写代码时,程序员还会说明代码的目标、谁编写的、在哪里需要、它做什么以及如何做、代码使用哪些其他资源等。

    技术文档增强了在同一代码上工作的不同程序员之间的理解。它增强了代码的可重用性。它使调试变得容易且可追溯。

    有各种可用的自动化工具,有些工具随编程语言本身一起提供。例如,Java提供了Javadoc工具来生成代码的技术文档。

  • 用户文档 - 该文档与上述所有文档不同。所有以前的文档都用于提供有关软件及其开发过程的信息。但是用户文档解释了软件产品应该如何工作以及如何使用它来获得期望的结果。

    这些文档可能包括软件安装程序、操作指南、用户指南、卸载方法以及获取更多信息的特殊参考,例如许可证更新等。

软件实现挑战

在软件实现过程中,开发团队面临一些挑战。其中一些列举如下:

  • 代码重用 - 当今编程语言的编程接口非常复杂,并配备了大量的库函数。尽管如此,为了降低最终产品的成本,组织管理层更倾向于重用之前为其他软件创建的代码。程序员在兼容性检查以及决定重用多少代码方面面临着巨大的问题。

  • 版本管理 - 每次向客户发布新软件时,开发人员都必须维护版本和配置相关的文档。这些文档需要高度准确并及时提供。

  • 目标主机 - 组织正在开发的软件程序需要针对客户端的宿主机器进行设计。但有时,不可能设计出一个在目标机器上都能正常工作的软件。

广告