编程方法 - 快速指南


编程方法 - 简介

当开发程序来解决库存管理、工资处理、学生招生、考试结果处理等实际问题时,它们往往庞大而复杂。分析此类复杂问题、规划软件开发和控制开发过程的方法称为编程方法论

编程方法的类型

软件开发人员中普遍存在多种类型的编程方法 -

过程式编程

问题被分解为过程或代码块,每个过程或代码块执行一项任务。所有程序加在一起就构成了整个程序。它仅适用于复杂性较低的小型程序。

示例- 对于执行加法、减法、乘法、除法、平方根和比较的计算器程序,这些操作中的每一个都可以开发为单独的程序。在主程序中,每个过程将根据用户的选择被调用。

面向对象编程

这里的解决方案围绕作为问题一部分的实体或对象。该解决方案涉及如何存储与实体相关的数据、实体如何Behave以及它们如何相互交互以提供一个有凝聚力的解决方案。

示例- 如果我们必须开发工资管理系统,我们将拥有员工、工资结构、休假规则等实体,必须围绕这些实体构建解决方案。

函数式编程

在这里,问题或所需的解决方案被分解为功能单元。每个单位执行自己的任务并且自给自足。然后将这些单元缝合在一起以形成完整的解决方案。

示例- 工资单处理可以具有员工数据维护、基本工资计算、总工资计算、休假处理、贷款偿还处理等功能单元。

逻辑编程

这里问题被分解为逻辑单元而不是功能单元。例如:在学校管理系统中,用户有非常明确的角色,如班主任、科目老师、实验室助理、协调员、学术负责人等。因此,软件可以根据用户角色划分为多个单元。每个用户可以有不同的界面、权限等。

软件开发人员可以选择这些方法中的一种或多种方法的组合来开发软件。请注意,在讨论的每种方法中,问题都必须分解为更小的单元。为此,开发人员使用以下两种方法之一 -

  • 自上而下的方法
  • 自下而上的方法

自上而下或模块化方法

问题被分解为更小的单元,而这些单元又可以进一步分解为更小的单元。每个单元称为一个模块。每个模块都是一个自给自足的单元,拥有执行其任务所需的一切。

下图显示了如何在开发工资单处理程序时遵循模块化方法来创建不同模块的示例。

薪资处理

自下而上的方法

在自下而上的方法中,系统设计从最低级别的组件开始,然后将这些组件互连以获得更高级别的组件。这个过程一直持续到生成所有系统组件的层次结构为止。然而,在现实生活中,一开始就知道所有最低级别的组件是非常困难的。因此自下而上的方法仅用于非常简单的问题。

让我们看一下计算器程序的组件。

自下而上的方法

了解问题

典型的软件开发过程遵循以下步骤 -

  • 需求收集
  • 问题定义
  • 系统设计
  • 执行
  • 测试
  • 文档
  • 培训和支持
  • 维护

前两个步骤有助于团队理解问题,这是获得解决方案最关键的第一步。负责收集需求、定义问题和设计系统的人员称为系统分析师

需求收集

通常,客户或用户无法清楚地定义他们的问题或要求。他们对自己想要什么有一个模糊的想法。因此,系统开发人员需要收集客户需求,以了解需要解决的问题或需要交付的内容。只有首先了解正在开发解决方案的业务领域,才能详细了解问题。有助于理解业务的一些关键问题包括 -

  • 正在做什么?
  • 进展如何?
  • 任务的频率是多少?
  • 决策或交易量是多少?
  • 遇到了哪些问题?

一些有助于收集这些信息的技术是 -

  • 采访
  • 问卷调查
  • 研究现有的系统文档
  • 分析业务数据

系统分析师需要创建清晰、简洁但全面的需求文档,以便识别 SMART(具体的、可测量的、商定的、现实的和基于时间的)需求。如果不这样做会导致 -

  • 问题定义不完整
  • 计划目标不正确
  • 重新工作以向客户提供所需的结果
  • 成本增加
  • 延迟交货

由于所需信息的深度,需求收集也称为详细调查

问题定义

收集需求并分析后,必须清楚地陈述问题。问题定义应该明确说明需要解决什么问题。必须有一个明确的问题陈述 -

  • 定义项目范围
  • 保持团队专注
  • 让项目步入正轨
  • 验证项目结束时是否达到了预期结果

确定解决方案

通常,编码被认为是任何软件开发过程中最重要的部分。然而,编码只是过程的一部分,如果系统设计正确,实际上可能会花费最少的时间。在设计系统之前,必须为当前问题确定解决方案。

关于设计系统,首先要注意的是,系统分析师最初可能会提出多个解决方案。但最终的解决方案或产品只能是一种。对需求收集阶段收集的数据进行深入分析有助于得出独特的解决方案。正确定义问题对于找到解决方案也至关重要。

当面临多个解决方案的问题时,分析师会借助流程图、数据流图、实体关系图等视觉辅助工具来深入理解每个解决方案。

流程图

流程图是通过符号和图表说明系统中的工作流程和数据流的过程。它是帮助系统分析师确定问题解决方案的重要工具。它直观地描述了系统的组件。

流程图

这些是流程图的优点 -

  • 视觉表示有助于理解程序逻辑

  • 它们充当实际程序编码的蓝图

  • 流程图对于程序文档很重要

  • 流程图是程序维护过程中的重要辅助工具

这些是流程图的缺点 -

  • 复杂的逻辑无法用流程图来描述

  • 如果逻辑或数据/工作流程发生任何变化,流程图必须完全重新绘制

数据流程图

数据流图或 DFD 是通过系统或子系统的数据流的图形表示。每个流程都有自己的数据流,并且有层次的数据流图。0级显示整个系统的输入和输出数据。然后系统被分解为模块,1级DFD分别显示每个模块的数据流。如果需要,模块可以进一步分解为子模块并绘制 2 级 DFD。

伪代码

系统设计完成后,交给项目经理实施,即编码。程序的实际编码是用编程语言完成的,只有接受过该语言培训的程序员才能理解。然而,在实际编码之前,程序的基本操作原理、工作流程和数据流是使用与要使用的编程语言类似的符号来编写的。这种表示法称为伪代码

下面是 C++ 伪代码的示例。程序员只需要将每条语句翻译成C++语法即可得到程序代码。

伪代码

识别数学运算

计算机的所有指令最终都以机器级别的算术和逻辑运算的形式实现。这些操作很重要,因为它们 -

  • 占用内存空间
  • 花时间执行
  • 确定软件效率
  • 影响软件整体性能

系统分析师试图识别所有主要的数学运算,同时确定手头问题的独特解决方案。

应用模块化技术

现实生活中的问题既复杂又庞大。如果开发整体解决方案,则会带来以下问题 -

  • 编写、测试和实施一个大程序很困难

  • 最终产品交付后进行修改几乎是不可能的

  • 程序维护非常困难

  • 一个错误就可能导致整个系统停止运行

为了克服这些问题,解决方案应该分为更小的部分,称为模块。将一个大的解决方案分解为更小的模块以便于开发、实现、修改和维护的技术称为编程或软件开发的模块化技术

模块化编程的优点

模块化编程具有以下优点 -

  • 由于每个模块都可以并行开发,因此可以实现更快的开发

  • 模块可以重复使用

  • 由于每个模块都是独立测试,因此测试更快、更稳健

  • 整个程序的调试和维护更加容易

  • 模块更小,复杂性更低,因此很容易理解

识别模块

识别软件中的模块是一项令人难以置信的任务,因为没有一种正确的方法可以做到这一点。以下是识别模块的一些指示 -

  • 如果数据是系统最重要的元素,请创建处理相关数据的模块。

  • 如果系统提供的服务多种多样,则将系统分解为功能模块。

  • 如果一切都失败了,请在需求收集阶段根据您对系统的理解将系统分解为逻辑模块。

对于编码,每个模块必须再次分解为更小的模块,以便于编程。这可以再次使用上面分享的三个技巧并结合特定的编程规则来完成。例如,对于像 C++ 和 Java 这样的面向对象编程语言,每个类及其数据和方法可以形成单个模块。

分步解决方案

为了实现模块,必须逐步描述每个模块的处理流程。可以使用算法伪代码来开发逐步解决方案。提供分步解决方案具有以下优点 -

  • 任何阅读解决方案的人都可以理解问题和解决方案。

  • 程序员和非程序员同样可以理解。

  • 在编码过程中,每个语句只需转换为程序语句即可。

  • 它可以成为文档的一部分并协助程序维护。

  • 诸如标识符名称、所需操作等微观细节会自动计算出来

让我们看一个例子。

接受费用支付

控制结构

正如您在上面的示例中所看到的,程序逻辑不必按顺序运行。在编程语言中,控制结构根据给定的参数做出有关程序流程的决策。它们对于任何软件来说都是非常重要的元素,必须在任何编码开始之前进行识别。

算法和伪代码可帮助分析师和程序员确定何处需要控制结构。

控制结构分为以下三种类型 -

决策控制结构

当要执行的下一步取决于某个标准时,将使用决策控制结构。这一条件通常是一个或多个必须计算的布尔表达式。布尔表达式的计算结果始终为“真”或“假”。如果条件为“真”,则执行一组语句,如果条件评估为“假”,则执行另一组语句。例如,如果语句

选择控制结构

当程序顺序取决于特定问题的答案时,使用选择控制结构。例如,一个程序为用户提供了许多选项。接下来要执行的语句将取决于所选的选项。例如switch语句、case语句。

重复/循环控制结构

当一组语句需要重复多次时使用重复控制结构。重复次数可能在开始之前已知,或者可能取决于表达式的值。例如for语句、while语句、do while语句等。

循环控制结构

正如您在上图中所看到的,选择和决策结构在流程图中的实现方式类似。选择控制只不过是一系列按顺序执行的决策语句。

以下是程序中的一些示例,展示了这些语句如何工作 -

决策结构

决策结构

编写算法

解决任何问题必须遵循的一组有限步骤称为算法。算法通常是在实际编码完成之前开发的。它是使用类似英语的语言编写的,因此即使非程序员也很容易理解。

有时,算法是使用伪代码编写的,即与要使用的编程语言类似的语言。编写解决问题的算法具有以下优点 -

  • 促进团队成员之间的有效沟通

  • 能够分析手头的问题

  • 充当编码蓝图

  • 协助调试

  • 成为软件文档的一部分,供将来维护阶段参考

这些是良好且正确的算法的特征 -

  • 有一组输入

  • 步骤是唯一定义的

  • 步数有限

  • 产生所需的输出

算法示例

让我们首先举一个创建算法的现实情况的例子。这是去市场购买钢笔的算法。

算法示例

该算法中的步骤 4 本身就是一个完整的任务,可以为其编写单独的算法。现在让我们创建一个算法来检查数字是正数还是负数。

算法示例

流程图元素

流程图是程序逻辑步骤序列的图形表示。流程图使用简单的几何形状来描述流程,并使用箭头来显示关系和流程/数据流。

流程图符号

以下是绘制流程图时使用的一些常见符号的图表。

象征 符号名称 目的
开始 停止 开始/停止 用在算法的开始和结束处,显示程序的开始和结束。
过程 过程 表示数学运算等过程。
输入输出 输入输出 用于表示程序的输入和输出。
决定 决定 代表程序中的决策语句,答案通常是“是”或“否”。
箭 显示不同形状之间的关系。
页面连接器 页面连接器 连接流程图中同一页面上的两个或多个部分。
离页连接器 离页连接器 连接分布在不同页面上的流程图​​的两个部分。

流程图开发指南

在开发流程图时需要记住以下几点 -

  • 流程图只能有一个开始和一个停止符号

  • 页面连接器使用数字进行引用

  • 使用字母引用页外连接器

  • 一般流程是从上到下或从左到右

  • 箭头不应相互交叉

流程图示例

这是去市场买笔的流程图。

流程图示例

这是计算两个数字的平均值的流程图。

流程图示例

使用清晰的说明

如您所知,计算机本身并不具有智能;它只是遵循用户给出的指示。指令是计算机程序的构建块,因此也是软件的构建块。给出明确的指示对于构建成功的计划至关重要。作为程序员或软件开发人员,您应该养成编写清晰指令的习惯。这里有两种方法可以做到这一点。

表达清晰

程序中的表达式是一系列运算符和操作数,用于进行算术或逻辑计算。以下是一些有效表达式的示例 -

  • 比较两个值
  • 定义变量、对象或类
  • 使用一个或多个变量的算术计算
  • 从数据库检索数据
  • 更新数据库中的值

编写明确的表达式是每个程序员都必须培养的技能。编写此类表达式时需要记住以下几点 -

明确的结果

表达式的求值必须给出一个明确的结果。例如,应谨慎使用一元运算符。

明确

避免复杂的表达式

不要试图通过一次表达来实现许多目标。当事情开始变得复杂时,分成两个或多个表达式。

说明简单

不仅仅是计算机需要编写清晰的指令。任何稍后阅读该程序的人(甚至您自己!!)都应该能够理解该指令试图实现的目标。对于程序员来说,当他们在一段时间后重新访问自己的程序时,无法掌握其窍门是很常见的。这表明此类程序的维护和修改将是相当困难的。

编写简单的指令有助于避免这个问题。以下是编写简单指令的一些技巧 -

  • 避免聪明的指令- 如果没有人能够正确理解它,那么聪明的指令以后可能看起来并不那么聪明。

  • 每项任务一条指令- 尝试一次做不止一件事会使指令变得复杂。

  • 使用标准- 每种语言都有其标准,请遵循它们。请记住,您并不是独自完成该项目;遵循项目标准和编码指南。

正确的编程技巧

在本章中,我们将介绍如何编写一个好的程序。但在此之前,让我们看看一个好的程序有哪些特征 -

  • 便携式- 程序或软件应在所有相同类型的计算机上运行。相同类型是指为个人计算机开发的软件应该在所有 PC 上运行。或者,为平板电脑编写的软件应该在具有正确规格的所有平板电脑上运行。

  • 高效- 快速完成指定任务的软件被认为是高效的。代码优化和内存优化是提高程序效率的一些方法。

特色好节目
  • 有效- 该软件应该有助于解决手头的问题。据说能够做到这一点的软件是有效的。

  • 可靠- 每次给出相同的输入集时,程序应该给出相同的输出。

  • 用户友好- 程序界面、可点击的链接和图标等应该是用户友好的。

  • 自文档化- 任何程序或软件的标识符名称、模块名称等都可以由于使用显式名称而描述自身。

以下是编写优秀程序的一些方法。

正确的标识符名称

标识任何变量、对象、函数、类或方法的名称称为标识符。给出正确的标识符名称可以使程序自我记录。这意味着对象的名称将说明它的用途或存储的信息。我们以这条 SQL 指令为例:

正确的标识符名称

看第 10 行。它告诉阅读该程序的任何人要选择学生的 ID、姓名和学号。变量的名称使得这一点不言自明。这些是创建正确的标识符名称的一些技巧 -

  • 使用语言指南

  • 不要回避使用长名称以保持清晰

  • 使用大写和小写字母

  • 即使语言允许,也不要为两个标识符提供相同的名称

  • 不要为多个标识符赋予相同的名称,即使它们具有互斥的范围

评论

在上图中,查看第 8 行。它告诉读者接下来的几行代码将检索要生成成绩单的学生列表。该行不是代码的一部分,只是为了使程序更加用户友好而给出。

这种不被编译而是作为程序员注释或解释而编写的表达式称为注释。请看下面程序段中的注释。注释以 // 开头。

评论

评论可以插入为 -

  • 该计划的序言解释其目标

  • 在逻辑或功能块的开头和/或结尾

  • 记下特殊情况或例外情况

您应该避免添加多余的注释,因为这可能会在阅读时破坏代码流程,从而适得其反。编译器可能会忽略注释和缩进,但读者倾向于阅读其中的每一项。

缩进

文本距左边距或右边距的距离称为缩进。在程序中,缩进用于分隔逻辑上独立的代码块。这是缩进程序段的示例:

缩进

正如你所看到的,缩进的程序更容易理解。从for 循环if再回到for 的控制流程非常清晰。缩进对于控制结构特别有用。

插入空格或行也是缩进的一部分。以下是一些您可以并且应该使用缩进的情况 -

  • 程序内逻辑或功能代码块之间的空行

  • 运算符周围的空白

  • 新控制结构开头的选项卡

编程方法——调试

识别并消除程序或软件中的错误称为调试。理想情况下,调试是测试过程的一部分,但实际上它是在编程的每个步骤中完成的。编码人员应该在继续之前调试最小的模块。这减少了测试阶段出现的错误数量,并显着减少了测试时间和工作量。让我们看一下程序中可能出现的错误类型。

语法错误

语法错误是程序中的语法错误。每种语言都有自己的一套规则,例如创建标识符、编写表达式等来编写程序。当违反这些规则时,错误称为语法错误。许多现代集成开发环境可以在您键入程序时识别语法错误。否则,编译程序时会显示出来。让我们举个例子 -

语法错误

在此程序中,变量 prod 尚未声明,这是编译器抛出的。

语义错误

语义错误也称为逻辑错误。该语句没有语法错误,因此可以正确编译并运行。但是,由于逻辑不正确,它不会给出所需的输出。让我们举个例子。

语义错误

看第13行。这里程序员想要检查除数是否为0,以避免被0除。但是,没有使用比较运算符==,而是使用了赋值运算符=。现在,每次“if 表达式”的计算结果为 true,程序都会给出输出“你不能除以 0”。绝对不是我们想要的!!

任何程序都无法检测到逻辑错误;当未达到期望的输出时,程序员必须自己识别它们。

运行时错误

运行时错误是在执行程序时发生的错误。这意味着该程序没有语法错误。您的程序可能遇到的一些最常见的运行时错误是 -

  • 无限循环
  • 除以“0”
  • 用户输入的值错误(例如,字符串而不是整数)

代码优化

任何修改代码以提高其质量和效率的方法都称为代码优化。代码质量决定代码的寿命。如果代码可以长期使用和维护,并在产品之间延续,那么它的质量就被认为是高的,并且具有更长的寿命。相反,如果一段代码只能在很短的时间内使用和维护,比如直到一个版本有效,那么它就被认为是低质量的,并且寿命很短。

代码的可靠性和速度决定了代码的效率。代码效率是确保软件高性能的重要因素。

代码优化有两种方法 -

  • 基于直觉的优化(IBO) - 在这里,程序员尝试根据自己的技能和经验来优化程序。这可能适用于小型程序,但随着程序复杂性的增加而惨遭失败。

  • 基于证据的优化(EBO) - 这里使用自动化工具找出性能瓶颈,然后相应地优化相关部分。每种编程语言都有自己的一套代码优化工具。例如,PMD、FindBug 和 Clover 用于优化 Java 代码。

由于时间稀缺且内存昂贵,代码针对执行时间和内存消耗进行了优化。两者之间必须保持平衡。如果时间优化增加了内存负载或者内存优化使代码变慢,那么优化的目的就会丧失。

交换两个变量

执行时间优化

为了向用户提供快速服务,有必要优化代码的执行时间。以下是一些执行时间优化的技巧 -

  • 使用具有内置执行时间优化的命令

  • 使用 switch 代替 if 条件

  • 最小化循环结构内的函数调用

  • 优化程序中使用的数据结构

内存优化

如您所知,数据和指令都会消耗内存。当我们说数据时,它也指作为表达式结果的临时数据。我们还需要跟踪有多少指令组成了我们试图优化的程序或模块。以下是内存优化的一些技巧-

  • 使用具有内置内存优化的命令

  • 尽量减少需要存储在寄存器中的变量的使用

  • 避免在多次执行的循环内声明全局变量

  • 避免使用 sqrt() 等 CPU 密集型函数

程序文档

任何向用户描述软件或程序的书面文本、插图或视频都称为程序或软件文档。用户可以是从程序员、系统分析师、管理员到最终用户的任何人。在开发的各个阶段,可能会为不同的用户创建多个文档。事实上,软件文档是整个软件开发过程中的一个关键过程。

在模块化编程中,文档变得更加重要,因为软件的不同模块是由不同的团队开发的。如果开发团队以外的任何人想要或需要了解模块,良好且详细的文档将使任务变得更容易。

这些是创建文档的一些指南 -

  • 文档应该从读者的角度出发

  • 文件应该明确

  • 不应有重复

  • 应使用行业标准

  • 文件应始终更新

  • 任何过时的文件应在适当记录淘汰后逐步淘汰

文档的优点

这些是提供程序文档的一些优点 -

  • 跟踪软件或程序的所有部分

  • 维护更容易

  • 开发人员以外的程序员可以了解软件的各个方面

  • 提高软件的整体质量

  • 协助用户培训

  • 确保知识分散,在人们突然离开系统时削减成本和精力

示例文档

软件可以有多种类型的与其关联的文档。一些重要的包括 -

  • 用户手册- 它描述了最终用户使用软件不同功能的说明和程序。

  • 操作手册- 它列出并描述了正在执行的所有操作及其相互依赖性。

  • 设计文档- 它概述了软件并详细描述了设计元素。它记录了数据流图、实体关系图等详细信息。

  • 需求文档- 它包含系统所有需求的列表以及需求可行性的分析。它可以有用户案例、现实生活场景等。

  • 技术文档- 它是实际编程组件的文档,例如算法、流程图、程序代码、功能模块等。

  • 测试文档- 它记录测试计划、测试用例、验证计划、验证计划、测试结果等。测试是软件开发的一个阶段,需要大量文档。

  • 已知错误列表- 每个软件都有无法删除的错误或错误,因为它们要么很晚才发现,要么是无害的,要么需要花费更多的精力和时间来纠正。这些错误与程序文档一起列出,以便以后可以将其删除。如果错误被激活,他们还会帮助用户、实施者和维护人员。

程序维护

程序维护是在交付后修改软件或程序以实现这些结果中的任何一个的过程 -

  • 纠正错误
  • 提高绩效
  • 添加功能
  • 删除过时的部分

尽管人们普遍认为需要维护来修复软件上线后出现的错误,但实际上大多数维护工作都涉及向现有模块添加次要或主要功能。例如,报告中添加了一些新数据,输入表单中添加了新字段,修改代码以纳入更改后的政府法律等。

维护类型

维护活动可分为四个标题 -

  • 纠正性维护- 修复了现场实施后出现的错误。错误可由用户自行指出。

  • 预防性维护- 为避免将来发生错误而进行的修改称为预防性维护。

  • 适应性维护- 工作环境的变化有时需要修改软件。这称为适应性维护。例如,如果政府的教育政策发生变化,学校管理软件的学生成绩处理模块也必须做出相应的改变。

  • 完美维护- 对现有软件进行的更改以纳入客户的新要求称为完美维护。这里的目标是始终掌握最新技术。

维修工具

软件开发人员和程序员使用许多工具来协助他们进行软件维护。以下是一些最广泛使用的 -

  • 程序切片器- 选择将受更改影响的程序部分

  • 数据流分析器- 跟踪软件中所有可能的数据流

  • 动态分析器- 跟踪程序执行路径

  • 静态分析器- 允许对程序进行一般查看和总结

  • 依赖分析器- 帮助理解和分析程序不同部分的相互依赖关系