软件工程基础
1. 软件
1.1 软件
- 软件是程序、数据、文档构成的集合
- CMU SEI的Watts Humphrey指出:软件产品必须首先提供用户所需要的功能,如果做不到这一点,什么产品都没有意义。
1.2 软件分类
- 系统软件
操作系统、编译程序、汇编程序、网络软件、数据库管理系统
- 应用软件
事物处理软件、工程与科学计算软件、实时处理软件、人工智能软件
- 支撑软件(工具软件)
需求分析工具软件、编译工具软件、测试工具软件、维护工具软件
1.3 软件危机
- 需求增长
- 开发难控
- 质量难保
- 难以维护
- 成本提高
- 生产率低
2. 软件工程
2.1 软件工程的概念
-
==软件工程:==应用于计算机软件的定义、开发和维护的一整套方法、工具、文档、实践标准和工序。
-
其目的是提高软件生产率、提高软件质量、降低软件成本
-
其核心思想是把软件当作一个工程产品来处理
2.2 软件工程三要素
- 方法是完成软件工程项目的技术手段
- 工具支持软件的开发、管理和文档生成
- 过程支持软件开发的个环节的控制和管理
2.3 软件生命周期
- 将软件产品从提出、实现、使用维护到停止使用退役的过程称为软件生命周期
- 分为软件定义、软件开发及软件运行维护3个时期。维护是持续时间最长,花费代价最大的一个时期。
- 软件工程学的一个目的就是提高软件的可维护性,降低维护代价
2.4 软件生命周期3个时期的8个阶段
- 定义阶段:
- 问题定义可行性研究
- 需求分析
- 开发阶段:
- 概要设计
- 详细设计
- 实现
- 测试
- 运行维护阶段
- 使用
- 维护
2.5 软件需求分析
-
需求分析:确定系统的逻辑模型。参加人员有用户、项目负责人和系统分析员。
-
其工作:
- 需求获取
需求获取的目的是确定对目标系统的各方面需求。涉及到的主要任务是建立获取用户需求的方法框架,并支持和监控需求获取的过程。
- 需求分析
-
需求分析是对获取的需求进行分析和综合,最终给出系统的解决方案和目标系统的逻辑模型。
-
软件需求是指用户对目标软件软件系统在功能、行为、性能、设计约束等方面的期望。需求分析的任务是发展需求、求精、建模和定义需求的过程。需求分析将创建所需的数据模型、功能模式和控制模型。
- 编写需求规格说明书
编写需求规格说明书作为需求分析的阶段成果,可以为用户、分析人员和设计人员之间的交流提供方便,可以直接支持目标软件系统的确认,又可以作为控制软件开发进程的依据。
- 需求评审
需求评审是对需求分析阶段的工作进行复审,验证需求文档的一致性、可行性、完整性和有效性。
-
产生文档:为需求规格说明书
-
需求规格说明书的作用:
- 便于用户、开发人员进行理解交流;
- 反映用户问题的结构,可以作为软件开发工作的基础和依据;
- 作为确认测试和验收的依据。
2.6 软件需求规格说明书(SRS)
需求分析阶段产生的主要文档是“软件需求规格说明书”,其特点是:
- 正确性:体现待开发系统的真实要求
- 无歧义性:对每个需求只有一种解释
- 完整性:包括全部有意义的需求
- 可验证性:每个需求都是可验证的
- 一致性:各个需求的描述不矛盾
- 可理解性:需求说明书必须简明易懂
- 可修改性:结构风格在改变时,是易于实现的
- 可追踪性:每个需求的来源和流向是清晰的
2.7 软件需求规格说明的内容
-
软件需求规格说明应重点描述软件的目标,软件的功能需求、性能需求、外部接口、属性及约束条件等。
- 功能需求是软件需求规格说明,给出软件要执行什么功能的详细描述。
- 性能需求是指定量地描述软件系统应该满足的具体性能需求,即各种软件功能的速度、响应时间、恢复时间。
- 外部接口指软件如何与人、系统的硬件及其他硬件和其他软件进行交互。
- 属性是指与软件有关的质量属性,如正确性、可用性、可靠性、安全性、可维护性等。
- 约束条件包括影响软件实现的各种设计约束,如使用的标准、编程语言、数据库完整性方针、资源限制、运行环境等方面的要求。
2.8 软件需求规格说明书的作用
- 便于用户和开发人员进行理解和交流。
- 反映出用户问题的结构,可以作为软件开发工作的基础和依据。
- 作为确认测试和验收的依据。
3. 结构化分析方法
3.1 需求分析方法有:
- 结构化需求分析方法
- 面向对象的分析方法
-
结构化分析方法:
-
使用数据流图(DFD)
-
数据字典(DD)
-
判定表
-
判定树
等工具,来建立系统的逻辑模型
-
3.2 数据流图(DFD)
- 数据流图的图形元素
加工:输入数据经加工变换产生输出
数据流:沿箭头方向传递数据的通道
存储文件(数据源):存放各种数据的文件
源(潭):系统和环境的接口
- 数据流图的作用
数据流图是描述数据处理过程的工具,是需求理解的逻辑模型的图形表示,它直接支持系统的功能建模。
数据流图中,数据流指暂时保存的数据,它可以是数据库文件或任何形式的数据组织,数据存储间不应该有数据流。
数据流图中除了流向数据存储或从数据存储流出的数据不必命名外,每个数据流必须要有一个合适的名字,以反映该数据流的含义。
相邻两层DFD之间具有父、子关系,子图代表了父图中某个加工的详细描述,父图表示了子图间的接口。
子图个数不大于父图中的处理个数。所有子图的输入、输出数据流和父图中相应处理的输入、输出数据流必须一致。
3.3 数据字典(DD)
数据字典是对数据流图中所有元素定义的集合,数据字典是结构化分析的核心
- 数据字典的作用
数据字典(Data Dictionary,简称DD)就是用来定义数据流图中的各个成分的具体含义的,它以一种准确的、无二义性的说明方式为系统的分析、设计及维护提供了有关元素的一致的定义和详细的描述。
4. 结构化设计方法
4.1 软件设计的划分
- 从工程管理角度划分:概要设计 详细设计
- 按技术观点划分:结构设计 数据设计 接口设计 过程设计
结构设计是定义软件系统各主要部件之间的关系;
数据设计是将分析时创建的模型转化为数据结构的定义;
接口设计是描述软件内部、软件和操作系统之间及软件与人之间如何通信;
过程设计则是把系统结构部件转换成软件的过程性描述。
4.2 结构化程序设计方法
==逐步求精:==对复杂的问题,应设计一些子目标作过渡,逐步细化
==自顶向下:==程序设计时应先考虑总体,后考虑细节;先考虑全局目标,后考虑局部目标。不要一开始就过多追求众多的细节,先从最上层总目标开始设计,逐步使问题具体化
==模块化:==一个复杂问题,肯定是由若干稍简单的问题构成。模块化是把程序要解决的总目标分解为分目标,再进一步分解为具体的小目标,把每个小目标称为一个模块,而可复用是面向对象程序设计的一个优点。
4.3 软件设计基本原理
4.2.1 抽象
在软件设计中,可以定出多个抽象级别,抽象层次从概要设计到详细设计逐步降低。
4.2.2 模块化
把一个待开发的软件分解成若干小的简单的部分,自顶向下逐层把软件划分成若干模块。
4.2.3 信息隐蔽
一个模块内的信息,对于不需要这些信息的其他模块来说不能访问。
4.2.4 模块独立性
每个模块只完成独立的子功能,并且与其他模块的联系少且接口简单。模块的独立程度是评价设计好坏的重要度量标准。
4.3 软件模块独立性
- 高内聚性:指一个模块内部各个元素间彼此结合的紧密程度
- 低耦合性:指模块间互相连接的紧密程度
4.4 概要设计
- 概要设计的任务
- 设计软件系统结构
- 数据结构及数据库设计
- 编写概要设计文档
- 概要设计文档评审
- 概要设计的工具是程序结构图(SC)
4.5 程序结构图
- 程序结构图的基本图符:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ejupYhJH-1647664553231)(images/程序结构图符.png)]
- 程序结构图的基本形式:
4.6 详细设计
- 详细设计的任务
确立每个模块的实现算法和局部数据结构,用适当方法表示算法和数据结构的细节
- 详细设计的常用工具
- 图形工具: 程序流程图 N-S图(方框图) PAD图 HIPO图
- 表格工具: 判定表
- 语言工具: PDL(伪码)
4.7 程序流程图
- 程序流程图的基本图符
4.8 软件系统结构图
使用结构图描述软件系统的层次和分块结构关系,它反映了整个系统的功能实现以及模块与模块之间的联系与通信,是未来程序中的控制层次体系。
- 深度:表示控制的层数。
- 宽度:表示整体控制跨度(最大模块数的层)。
- 扇入:是指直接调用该模块的上级模块的个数。扇入大表示模块的复用程序高。扇入的最大值称为最大扇入数。
- 扇出:是指该模块直接调用的下级模块的个数。扇出大表示模块的复杂度高,需要控制和协调过多的下级模块。扇出的最大值称为最大扇出数。
- 原子模块:树中位于叶子结点的模块。
4.9 软件设计的准则
-
大量的软件设计的实践证明,以下的设计准则可以借鉴为设计的指导和对软件结构图进行优化。这些准则是:
- 提高模块独立性;
- 模块规模适中;
- 深度、宽度、扇入和扇出适当;
- 使模块的作用域在该模块的控制域内;
- 应减少模块的接口和界面的复杂性;
- 设计成单入口、单出口的模块。
- 设计功能可预测的模块。
5. 软件测试
5.1 软件测试的目的是:
发现程序中的错误
5.2 软件测试的准则:
- 所有测试都应追溯到用户需求
- 在测试之前制定测试计划, 并严格执行
- 充分注意测试中的集群现象
- 避免由程序的编写者测试自己的程序
- 不可能进行穷举测试
- 妥善保存测试分析报告, 为维护提供方便
5.3 静态和动态测试
- 静态测试: 不实际运行软件, 通过人发挥思维优势发现程序的错误
- 动态测试: 基于计算机的测试, 是为了发现错误而执行程序的过程
5.4 集成测试
-
集成测试将模块组装成程序通常采用两种方式:非增量方式组装和增量方式组装。
- 非增量方式也称为一次性组装方式。将测试号的每一个软件单元一次组装在一起再进行整体测试。
- 增量方式包括自顶向下、自底向上、自顶向下和自底向上相结合的混 合增量方法。
5.5 白盒和黑盒测试
- 白盒测试: 把测试对象看作一个打开的盒子 ,利用程序内部的逻辑结构, 对程序所有逻辑路径进行测试
逻辑覆盖测试
程序中的逻辑表示有判断、分支、选择等
基本路径测试
- 黑盒测试: 完全不考虑程序内部的逻辑结构, 只检查程序是否能接收输入数据而产生正确的 输出信息
- 等价类划分法
- 边界值分析法
- 错误推测法
- 软件测试用例
软件测试用例由测试的输入数据和预期的输出结果两部分组成。
黑盒测试中,测试用例主要是依据需求进行编写。需求中描述软件需要完成的功能。
5.5 软件测试步骤
- 单元测试: 是对软件设计的最小单位–模块进行测试, 目的是发现各模块内部的错误
- 单元测试的依据是详细设计说明书和源程序。
- 代码编写阶段可以由开发人员进行单元测试,检测代码编写的各个单元的正确性。
-
单元测试主要针对模块的下列5个基本特性进行:
- 模块的接口测试
- 局部数据结构测试
- 重要的执行路径的检查
- 出错处理测试
- 影响以上各点及其他相关点的边界条件测试。
-
集成测试: 是把模块按照设计要求组装起来的同时进行测试, 目的是发现与接口有关的错误
-
确认测试: 是验证软件的功能和性能是否满足各种需求, 以及软件配置是否完全 正确
-
系统测试: 是将软件作为一个元素, 与计算机系统其他元素组合在一起, 进行集成测试
5.6 视图设计
视图设计一般有3种设计次序,它们分别是自顶向下、自底向上和由内向外,它们又为视图设计提供了具体的操作方法,设计者可根据实际情况灵活掌握,可以单独使用也可混合使用。
6. 程序的调试
6.1 概念
-
对程序进行了成功的测试之后将进入程序调试, 通常称为Debug(排错), 主要在开发阶段进行
-
程序调试的任务是诊断和改正程序的错误
6.2 基本步骤
- 错误定位
- 修改设计和代码, 以排除错误
- 进行回归测试, 防止引进新的错误
6.3 软件调试方法
- 强行排除法
- 回溯法
- 原因排除法