上一章软件工程教程请查看:软件设计复杂度
在本章中,我们将学习编程方法、文档和软件实现中的挑战。
结构化程序设计
在编码的过程中,代码行数不断增加,软件的规模也随之增大。渐渐地,几乎不可能记住程序的流程。如果一个人忘记了软件及其底层程序、文件、过程是如何构建的,那么共享、调试和修改程序就会变得非常困难。这个问题的解决方案是结构化编程。它鼓励开发人员使用子程序和循环,而不是在代码中使用简单的跳转,从而使代码变得清晰,并提高其效率,结构化编程也有助于程序员减少编码时间和正确组织代码。
结构化编程说明了如何对程序进行编码。结构化编程使用三个主要概念:
- 自顶向下的分析——软件总是用来执行一些理性的工作。这种理性的工作在软件术语中被称为问题。因此,了解如何解决这个问题是非常重要的。在自顶向下的分析中,问题被分解成小块,每一块都有一定的意义。每个问题都是单独解决的,并且清楚地说明了如何解决问题的步骤。
- 模块化编程——在编程时,代码被分解成更小的指令组。这些组称为模块、子程序或子例程。基于自顶向下分析理解的模块化编程。它不鼓励在程序中使用“goto”语句进行跳转,这通常会使程序流变得不可跟踪。在结构化编程中,禁止跳转,并鼓励使用模块化格式。
- 结构化编码——参考自顶向下的分析,结构化编码将模块按照执行的顺序细分为更小的代码单元。结构化编程使用控制结构,控制程序的流程,而结构化编码使用控制结构以可定义的模式组织指令。
函数式编程
函数式编程是一种使用数学函数概念的编程语言,数学中的一个函数总是在得到相同的参数时产生相同的结果。在过程语言中,程序的流程贯穿过程,即程序的控制被转移到被调用的过程中。当控制流从一个过程转移到另一个过程时,程序改变其状态。
在过程式编程中,当用相同的参数调用过程时,过程可能产生不同的结果,因为在调用过程中程序本身可能处于不同的状态。这是过程性编程的一个特性,也是它的一个缺点,在这个特性中,过程执行的顺序或时间变得非常重要。
函数式编程以数学函数的形式提供计算方法,不管程序状态如何,计算结果都是一样的。这使得预测程序的行为成为可能。
函数式编程使用以下概念:
- 第一类和高阶函数——这些函数能够接受另一个函数作为参数,或者返回其他函数作为结果。
- 纯函数——这些函数不包括破坏性的更新,也就是说,它们不影响任何I/O或内存,如果不使用它们,可以轻松地删除它们,而不会妨碍程序的其余部分。
- 递归——递归是一种编程技术,在这种技术中,函数调用自身并重复其中的程序代码,除非某些预定义的条件匹配。递归是函数式编程中创建循环的方法。
- 严格求值——它是作为参数传递给函数的表达式的求值方法。函数式编程有两种类型的求值方法,严格的(eager)和非严格的(lazy)。严格求值总是在调用函数之前对表达式求值。非严格计算不会计算表达式的值,除非需要。
- λ-calculus——大多数函数式编程语言使用λ-calculus类型系统。λ-expressions执行通过评估他们发生。
常见的Lisp、Scala、Haskell、Erlang和f#是函数式编程语言的一些例子。
编程风格
编程风格是所有程序员编写代码时所遵循的一套编码规则。当多个程序员在同一个软件项目中工作时,他们经常需要使用其他开发人员编写的程序代码。如果所有的开发人员都没有遵循某种标准的编程风格来编写程序,那么这就变得非常繁琐,有时甚至是不可能的。
适当的编程风格包括使用与预期任务相关的函数和变量名、使用适当的缩进、注释代码以方便读者阅读和整体呈现代码,这使得所有人都可以阅读和理解程序代码,从而使调试和错误解决变得更容易。此外,适当的编码风格有助于简化文档和更新。
编码指南
编码风格的实践因组织、操作系统和编码本身的语言而异。
根据组织的编码指引,可定义下列编码要素:
- 命名约定——本节定义如何命名函数、变量、常量和全局变量。
- 缩进——这是行首的剩余空间,通常是2-8个空白或单个制表符。
- 空格——通常在行尾省略。
- 运算符-定义数学运算符、赋值运算符和逻辑运算符的书写规则。例如,赋值运算符“=”的前面和后面应该有空格,如“x = 2”。
- 控制结构——只以嵌套方式编写if-then-else、case-switch、while-until和for控制流语句的规则。
- 行长度和换行—定义一行中应该有多少个字符,通常一行有80个字符长。换行定义了一行如果太长,应该如何换行。
- 函数——这定义了如何声明和调用函数,带有和不带有参数。
- 变量——这涉及到如何声明和定义不同数据类型的变量。
- 注释——这是重要的编码组件之一,因为代码中包含的注释描述了代码的实际功能以及所有其他相关的描述,本节还帮助其他开发人员创建帮助文档。
软件文档
软件文档是软件过程的重要组成部分,一个写得好的文档为了解软件过程提供了一个很好的工具和信息存储库,软件文档还提供了关于如何使用产品的信息。
妥善保存的文件应包括下列文件:
- 需求文档——此文档作为软件设计人员、开发人员和测试团队执行各自任务的关键工具。本文档包含了预期软件的所有功能、非功能和行为描述。
本文档的来源可以是以前存储的关于软件的数据,已经在客户端运行的软件,客户的访谈、问卷调查和研究。它通常以电子表格或文字处理文档的形式存储在高端软件管理团队中。
本文档是软件开发的基础,主要用于验证和验证阶段。大多数测试用例都是直接从需求文档中构建的。
- 软件设计文档——这些文档包含构建软件所需的所有必要信息。它包括:(a)高级软件架构,(b)软件设计细节,(c)数据流程图,(d)数据库设计
这些文档作为开发人员实现软件的存储库。虽然这些文档没有给出关于如何编码程序的任何细节,但是它们给出了编码和实现所需的所有必要信息。
- 技术文档——这些文档由开发人员和实际的程序员维护。这些文档作为一个整体,代表了关于代码的信息。在编写代码时,程序员还会提到代码的目标、谁编写了代码、在哪里需要它、它做什么以及如何做、代码使用什么其他资源等等。
技术文档增加了不同程序员对同一代码的理解。它增强了代码的重用能力。它使调试变得简单和可跟踪。
有各种各样的自动化工具可用,有些是随编程语言一起提供的。例如,java提供了JavaDoc工具来生成代码的技术文档。
- 用户文档—此文档不同于上述所有解释。维护所有以前的文档以提供关于软件及其开发过程的信息。但是用户文档解释了软件产品应该如何工作,以及如何使用它来获得期望的结果。
这些文件可能包括,软件安装程序,操作指南,用户指南,卸载方法和特殊的参考资料,以获得更多的信息,如许可证更新等。
软件实现的挑战
在实现软件时,开发团队面临一些挑战,其中一些列如下:
- 代码重用——当今语言的编程接口非常复杂,并且具有巨大的库函数。尽管如此,为了降低最终产品的成本,组织管理层更愿意重用为其他软件创建的代码。在兼容性检查和决定重用多少代码方面,程序员面临着巨大的问题。
- 版本管理——每当向客户发布一个新软件时,开发人员都必须维护与版本和配置相关的文档。此文档需要高度准确并及时可用。
- 目标主机——该组织正在开发的软件程序需要为客户端主机设计。但有时,不可能设计出在目标机器上运行的软件。
评论前必须登录!
注册