719 views
# 软件工程
<!-- > 吴妍 15204679973 成栋1034
> 阶段40%(传统软件工程学)+期末40%(面向对象软件工程学)+实验(4\*5)%
> 课件为主 -->
# 图大全
```markmap
# 软件工程
## 软件工程概述(软件工程模型)
### 基于生命周期
- 瀑布模型
- 增量模型
- RAD模型
### 基于原型
- 原型模型
- 螺旋模型
- 基于复用的过程模型
### 面向对象
- 喷泉模型
## 软件项目管理
### 4P
- 产品分解结构PBS
- 工作分解结构WBS
### **进度管理**
- 甘特图
- **工程网络图CPM(关键路径法)**
## 需求工程(结构化**分析**方法)
- 数据建模-实体关系图ERD
- 功能建模-(分层)数据流图DFD
- 行为建模-状态转换图STD
## 软件设计
### **结构化设计方法**
- 结构图SC
- **数据流图DFD(与SC的转化)**
### 过程设计描述工具
#### 图表工具
- 程序流程图(程序框图)
- N-S图(盒图)
- PAD图(问题分析图)
- 判定树(决策表)/判定表(决策树)
#### 语言工具
- PDL(过程设计语言)
## 软件测试
### 黑盒测试
#### 等价类与边界值分析
- 等价类表
#### 因果图法
- 因果图
- 约束关系
- 判定表
### **白盒测试**
- **程序控制流图**
## 面向对象的分析(UML)
```
# 1 软件工程概述
## 1.1 软件的概念、特点及分类
1. 软件的概念
* 软件是计算机系统中与硬件相互依存的部分。他是包括计算机程序、数据以及软件文档的完整集合
* 软件文档:与软件开发、使用和维护有关的各种图文材料
* 开发文档
与软件开发过程中的技术流程相关
面向软件开发人员
前一阶段开发成果的详细记录可作为后一阶段开发工作的依据:可行性研究报告->项目开发计划->软件需求规格说明书(SRS)->概要设计说明书->详细设计说明书
* 管理文档
与软件开发过程中的管理流程相关
面向软件管理人员
软件开发人员定期撰写计划与报告供管理人员掌握软件开发的进展
* 用户文档
与软件使用相关
面向软件用户
用户手册、操作手册、维护修改建议、**软件需求规格说明书(需求由用户制定,因此也纳入用户文档范畴)**
2. 软件的特点
* 软件是一种抽象的**逻辑实体**,不是具体的物理实体(抽象性)
* 软件产品没有明显的制造过程,其生产过程主要是开发
* 软件产品的维护比硬件复杂(存在退化问题,需要维护与更新)
* 软件的开发和运行对计算机系统存在依赖性(可移植性)
* 软件本身的复杂性(问题域的复杂性)
3. 软件的分类
1. 按功能划分
* 系统软件
操作系统、数据库管理系统、设备驱动程序
* 支撑软件
用于软件开发的工具性软件,如集成开发环境(Integrated Develop Environment,IDE)
* 应用软件
为特定领域开发,服务于特定目的的软件
2. 按规模划分
* 微型
* 小型
* 中型
* 大型
* 甚大型
* 极大型
3. 按开发方式
4. 按存在形式
5. ...
## 1.2 软件的发展及软件危机
1. 软件的发展
程序设计->程序系统(诸多问题集中爆发,引起软件危机)->软件工程
2. 软件危机(Software Crisis)
软件危机是指计算机软件在开发和维护过程中遇到的一系列严重问题
* 对软件开发成本和开发进度估算不准确,严重拖期或超出预算
* 无法满足用户需求,导致用户很不满意
* 软件可维护性差,难以更改、调试和增强
* 软件质量不可靠,经常失效
* 软件缺少必要适当的软件文档,使用不便
* ...
## 1.3 软件工程的概念及其三要素
1. 软件工程的产生
1968年,NATO科学委员会在讨论软件开发与设计、软件危机等的基础上提出了软件工程的概念
2. 软件工程的定义
Fritz Bauer:为了**经济地**能够获得在实际机器上有效运行的**可靠**软件,而建立并使用的一系列**工程化原则**。(工程学->软件开发)
IEEE:将系统性的、规范化的、可度量的方法应用于软件开发、运行和维护。
**软件工程是一门工程性学科,采用工程化的原则并结合有效的管理技术,以提高软件质量和生产率**
3. 软件工程的三个基本要素
软件工程以**软件质量为目标**,由**方法、工具、过程三个基本要素**组成
* 方法
1. 结构化方法
一种面向数据流的方法,适用于一般的数据处理系统
主要特征:
* 以结构化程序设计为基础
* 程序=数据结构+算法
* 结构化分析/设计/编程(SA/D/P)
2. 面向对象方法
主要运用对象、类、封装、继承,消息通信等概念来分析和构建软件系统
主要特征:
* 以面向对象程序设计为基础
* 程序=对象+消息通信
* 面向对象分析/设计/编程(OOA/D/P)
* 工具
软件开发工具
* 过程
规定了一系列软件工程活动,以及活动的执行步骤和细节
开发思维模式:
* 任务思维模式(早期)
* 过程思维模式(后期)
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/16-57-22-9ad13c16c9a990755dd68ab6cfb223a8-upload_05a8a8547103cb207d052c21eebc839e-fc3f32.jpeg =400x)
软件过程由一系列软件工程活动以及活动之间的关系组成;
通过一系列顺序和步骤执行这些活动;
产生如模型、代码、文档、数据等过程制品,取得预期的过程结果;
需要参与活动的人员和活动工具等过程资源的支持;
通过反馈和评审过程结果,实现过程的可持续改进。
## 1.4 软件工程的基本目标及基本原理
基本目标:
* **开发出高质量的软件(根本目标)**
* 付出较低的开发成本
* 实现预期要求的软件功能
* 取得较好的软件性能
* 软件易于移植(跨平台运行)
* 软件易于维护(问题修复与功能增加)
* 能够按时完成开发并及时交付使用
平衡以上各个因素的优先级,实现**整体质量的最优**
基本原理:
* 用分阶段的生命周期计划严格管理
* 坚持进行阶段评审
* 实行严格的*产品控制(严格评审任何软件需求的修改,减少资源浪费)*
* 采用现代程序设计技术
* 明确开发组织的责任和产品标准
* 开发小组的人员应该少而精
* 不断改进软件开发**过程**
## 1.5 软件生存周期(SLC)及软件工程模型(imp)
1. 软件生存周期
从软件产品最初定义开始,到交付用户使用,直至最终废弃淘汰的全过程。
软件生存周期阶段
制定计划$\rightarrow$需求分析$\rightarrow$软件设计$\rightarrow$程序编码$\rightarrow$软件测试$\rightarrow$运行维护
* 制定计划
问题定义(确认问题应用领域与实际需要解决的问题)+可行性研究
* 需求分析
针对用户软件需求,给出定义与分析,并给出**软件需求规格说明书**
* 软件设计
给出软件设计方案及策略(该阶段不设计任何具体代码层面)
* 程序编码
按设计阶段给出的原型图,完成代码编写与实现
* 软件测试
设计软件测试用例并对软件进行测试,检查软件的错误或缺陷
* 运行维护
2. 软件工程模型
软件工程模型是对软件开发过程的一种抽象表示,用来描述软件过程活动的流程框架
典型的软件过程模型:
* 瀑布模型(软件生命周期模型)
最早提出的传统模型,但**过于理想化**
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/16-59-08-d9a42b5c7fed439c70be104e325ef11f-upload_6daf6b450617609980e6ef39a409a1e2-b7765f.png =500x)
特点:
* 线性,各项活动严格按照时间次序上的线性关系,一个接一个地向前推进
* 特别侧重软件文档的作用,阶段之间都依赖其驱动
* 黑盒过程,开发过程缺乏用户交互与参与
* 简单易用,效率高。但灵活性差,难以响应用户需求的变化
* 仅适用于规模较小且需求稳定的软件项目
* 增量模型
增量:能够提供特定功能,且可以运行的功能模块
相比瀑布模型,分解为多个增量模块,每个增量采用瀑布模型开发
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/16-59-27-c2aadd1ee024fbc582d864bea999d32f-upload_9f5e4adabb1284161d47a37e0db82833-9d7fe5.png)
特点:
* 软件被作为一系列的增量分别进行开发,逐个增量地交付产品。第一个增量是软件核心,要满足基本需求,但可缺少附加特性。
* 用户通过使用上一个增量的提交物,进行评价,制定出下一个增量的计划,说明要增加的新特性和新功能。
* 每个增量都采用瀑布模型进行开发,形成多个瀑布模型的串行化。
* 需要软件具备开放式的体系结构。
* 能够适应用户逐步细化需求的过程,适用于不断增加新需求的软件项目。
* RAD模型
增量并行开发,进一步加快开发速度
特点:
* 多个增量并行开发,形成多个瀑布模型的并行化
* 每个增量都由一个独立的RAD团队完成,多个团队并行执行,提高开发效率
* 侧重于短开发周期(一般为60~90天)的增量模型
* 需要大量的人力资源创建多个RAD团队。
* 原型模型
原型:软件的一个早期雏形,要能反映最终软件系统的主要功能特性
* 抛弃型原型
原型不可执行,只为收集和验证用户需求
* 演化型原型
原型可执行,要求最初构造的原型具备较高质量,包含系统的核心功能,对其进行不断地完善和演化,直到用户满足为止
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/16-59-52-5f44872ac4e9aaccc1ec4229c1d2bb5c-upload_77a2dc0fa703f2fc21bb7bbf659561cb-a23f04.jpeg)
特点:
* **循环迭代**的软件开发过程
* 最大程度响应用户需求的变化,提高了用户参与度
* 利于用户培训和软件开发同步进行
* 适用于软件需求不明确,设计方案有风险的软件项目
* 螺旋模型
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-00-02-c7360f8fdacb7ebd37019a5408210f13-upload_504f6d6bd322d2a4d761cf0255d0c1de-7ed4ee.png)
每迭代一圈一般都经历四个基本活动:
* 制定计划:制定**当前开发阶段**的计划与目标
* 风险分析
* 实施工程
* 客户评估
特点:
* 将瀑布模型的线性特征与原型模型的迭代特征相结合(螺旋性推进瀑布模型的各个阶段)
* 将开发管理与**风险分析**相结合,引入风险分析,减小并控制软件风险
* 要求开发人员能够擅长软件风险的识别与排除
* 耗费时间长,投入成本高(牺牲时间与资源追求高质量)
* 适用于大型软件项目开发
* 基于**复用**的过程模型
软件复用:依赖现有的软件构件及其相应的集成框架,开发新的软件系统
主要过程:需求分析与定义$\rightarrow$体系结构设计$\rightarrow$构件获取$\rightarrow$构件修改与测$\rightarrow$构件组装集成$\rightarrow$完成系统的测试
特点:
* 降低开发风险和成本,提升开发效率
* 某些商业组件可能较难修改,使得系统的演化会受到一定的限制
# 2 软件项目管理
## 2.1 软件项目管理概述
软件项目的特性:
* 软件产品的不可见性
* 项目的高度不确定性
* 软件过程的多变化性
* 软件人员的高流动性
软件项目管理:为使软件项目能按照预定的成本、进度、质量顺利完成,而对成本、人员、进度、风险等进行分析和管理的活动。
### 2.1.2 4P
软件项目管理中的4P:
* People 人员
* Process 过程
* Project 项目
* Product 产品
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-00-30-6851adacdd062c5ca650951f6466f5a6-upload_56b514c15f167143eb75d907ae5d6869-474952.png =350x)
#### 2.1.2.1 People人员
* 软件项目的参与人员分类
* 高级管理者
* 项目管理者
* 开发人员
* 客户
* 最终用户
* 软件开发团队
* 选择人员组建软件开发团队时应考虑如下要素
* 项目需求
* 待解决问题的难度
* 待开发软件系统的规模
* 待开发软件系统的技能要求
* 交付日期的严格程度
* ...
* 个人能力
* 应用领域经验
* 开发平台经验
* 编程经验
* 沟通与团队协作能力
* ...
* 软件开发团队的组织架构
* 民主式组织结构
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-02-06-1638faea5464612947dae39eea764989-upload_48d7c2f9906436b6fcde9cf34375adae-cd1d2f.png =250x)
* 主程序员式组织结构
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-02-40-c4e32bd1eaafa21c3181ce4f7b92fdf5-upload_d4e83392fcab18037196b18e6856a158-6cd7af.png =250x)
* 技术管理式组织结构
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-02-54-d4f45c85348f8f2ac32e179edba74bbb-upload_7cd225b24c4764f49b6312910d6fb43b-f826b6.png =250x)
* 大型项目的层次式组织结构
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-03-08-4d2eef7dec3eb5dfb788cab71d2872d7-upload_c2f7db6dbb6646af0fd1b1414481b60a-a6fe72.png =550x)
| 组织方式 | 优点 | 缺点 |
| ------------------------ | -------------------------------------------------------------- | -------------------------------------------------- |
| 民主式组织结构 | 激发创造力,适于小规模的开发组 | 缺乏明确的领导,难以解决意见分歧,不适于大规模开发 |
| 主程序员式组织结构 | 实现了专业化分工,借助主程序员,简化了组内成员的沟通协调的难度 | 主程序员需要兼具技术才能与管理才能 |
| 技术管理式组织结构 | 将技术开发工作与行政管理工作分离,减轻领导者负担 | 难于明确划分技术经理与管理经理的管理权限 |
| 大型项目的层次式组织结构 | | |
#### 2.1.2.2 Product产品
* 在软件项目管理中,对软件产品的关注不仅仅是最终的软件系统,还包括**软件开发过程中的所有中间产出物**
* 需求分析
* 需求模型
* 原型
* 分析模型
* 结构化分析模型(chap 3)
* 面向对象分析模型(chap 6)
* 软件需求规格说明
* 软件设计
* 设计模型
* 软件体系结构描述
系统的基本构件及其之间的连接关系
* 软件实现
* 源代码
* 目标程序
* 可执行构件
* 软件测试
* 测试规程
* 测试环境
* 测试方法
* 测试步骤
* ...
* 测试用例
* 软件测试报告
* 软件运行
* 相关的运行时文件
* 用户手册
* 产品分解结构
* 软件项目管理中,通常使用"产品分解结构"(Product Breakdown Structure,PBS)作为产品分解的工具。
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-03-48-13e286458fd664d433cac8226013fb2c-upload_12304c3dac13ecc54ca35407bd1c39e6-b469a6.png)
#### 2.1.2.3 Process过程
* 在软件项目管理中,对软件过程主要关注以下方面
* 选择合适的软件过程模型
* 根据所选的过程模型,进行适应性修改
* 确定过程中应包含的工作任务列表
* 工作分解结构
* 软件项目管理中,通常使用"工作分解结构"(Work Breakdown Structure,WBS)作为过程分解的工具。
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-04-04-12e1df59c53692c51af408d96257a80d-upload_4b1b4fece1aa19ddb0f196b247b7f567-79dec0.png =300x)
#### 2.1.2.4 Project项目
* 对**软件项目本身**主要关注以下方面:
* 范围(Scope)
* 项目目标
* 主要功能
* 性能限制
* 系统接口(系统->硬件/软件/用户/...)
* 其他要求(可靠性,实时性,可定制性...)
* 进度(Time)
* 成本(Cost)
* 质量(Quality)
* ...
### 2.1.3 软件项目管理流程
软件项目管理的过程主要包括以下4个阶段:
* 项目启动
* 确定项目范围
* 组件项目团队
* 建立项目的基础设施
* 项目规划
* 确定项目活动
* 预算项目成本
* 制定进度计划
* 项目实施
* 监控项目执行
* 管理项目风险
* 控制项目变更
* 项目收尾
* 客户验收项目
* 安装培训软件
* 总结项目经验
## 2.2 软件项目估算
### 2.2.1 软件规模估算
软件规模是影响软件项目成本,工作量以及完成期限的重要因素
典型的软件规模估算技术
* 代码行技术(line of code,LOC)
* 功能点技术
### 2.2.1.1 代码行技术
* 这种方法根据**以往开发类似产品的经验**,估算所开发软件的代码行数
* 将软件分解成一系列可分别独立估算的子功能,通过估算每个子功能的代码行数并进行累加,得到整个软件系统的总代码行数
* 为了使估计值更接近于实际值$\begin{align}L=\frac{a+4m+b}{6}\end{align}$,即将乐观值,平均值,悲观值按1\:4\:1进行加权平均计算
* 成本$C$=每行代码的单位成本$\mu\times$估计代码行数$L$
* 工作量$PM$=估计代码行数$L/$平均生产率$v$
* 优点:简单方便
* 缺点:仅用源程序的规模代表整个软件的规模;估算结果与开发语言高度相关;需要依赖于较为详细的功能分解结果
### 2.2.1.2 功能点技术
* 这种方法根据软件信息域的基本特征和对软件复杂性的评估结果,估算所开发软件的规模
* 软件信息域的5个基本特征
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-04-18-a29430461600fe267c79a98c4de95b4a-upload_ed07545e416dffac08255947396fe7e6-8099cf.png =300x)
* 外部输入
* 外部输出
* 外部查询
* 外部接口
* 内部逻辑文件
* 基本步骤
1. 估算未调整的功能点数UFP
软件信息域中的每个特征都被划分为简单、中等、复杂3个等级,每个特征在不同等级上分配了不同的加权因子
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-04-30-6b1fe254b816741330428f13d1a98754-upload_8ec6ca26f074bf7d1642b1988a3713e3-185fc0.png)
2. 计算复杂度调节因子CAF
综合来看,影响软件规模的14种技术因素如下所述
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-04-37-68e38c08b0bc70b3563a982418754fec-upload_b7a23268eacfa6f213b13d2b2ebe6f91-cf7b88.png)
根据所开发软件的特点,估计上述每种影响因素$F_i$对软件规模的影响程度,共分为6个等级,分别用0~5来表示
* 0表示没有任何影响
* 1表示产生偶然影响
* 2表示产生轻度影响
* 3表示产生一般程度的影响
* 4表示产生重要影响
* 5表示产生非常重要的影响
可利用下列经验公式计算复杂度调节因子CAF
$CAF=0.65+0.01 \times \sum_{i=1}^{14} F_{i}$
CAF的值应在0.65~1.35之间,其中0.65被称为**基本调节常数**,最大调节量为±35%
3. 计算调整后的功能点数DFP
$DAF=UFP\times CAF$
经过复杂度调节因子CAF调整后的功能点数(DFP)被称为交付功能,上述计算出的**功能点数可以代表软件规模,也可以作为进一步估算成本和工作量的依据**
* 优点
估算结果(功能点数)**与所用的开发语言无关**,可以在开发初期进行估算
* 缺点
在判断信息域特征的复杂性等级以及判断技术因素对软件规模的影响程度时,都存在很大的**主观性**(因人而异)
### 2.2.2 软件工作量估算
#### 2.2.2.1 COCOMO模型
COCOMO(COnstructive COst MOdel,构造性成本模型)模型
COCOMO模型主要对工作量和开发时间进行估算
COCOMO模型是一种层次模型,大致可分为三层
* 第一层:基本模型
* 第二层:中级模型
* 第三层:详细模型
考虑到估算量与软件项目的类型有关,COCOMO模型主要针对下列三种类型的软件项目进行估算
* 组织型
规模相对较小、较为简单的软件项目,比如,各种小型应用软件
* 嵌入型
通常是与某些硬件设备紧密结合的项目,比如,飞行控制系统、大型操作系统、实时处理系统、航天控制系统
* 半独立型
项目性质介于以上两种类型之间,其规模与复杂度均属于中等。比如,编译系统、数据库管理系统
基本COCOMO模型
* 基本COCOMO模型是一个**静态单变量模型**,它以估算出的**源代码行数(基于LOC法)** 来计算软件开发工作量,其估算公式如下:$\left\{\begin{array}{c}E=a_{1} \times L^{b_{1}} \\D=c_{1} \times E^{d_{1}}\end{array}\right.$
$E$——工作量(单位:人月)
$L$——估计的代码行数(单位:KLOC)
$D$——所需的开发时间(单位:月)
* $a_1$和$c_1$是模型系数,$b_1$和$d_1$是模型指数,均为常数,其值与软件项目的类型有关,基本COCOMO模型系数表如下:
| 类型 | $a_1$ | $b_1$ | $c_1$ | $d_1$ |
| -------- | ----- | ----- | ----- | ----- |
| 组织型 | 2.4 | 1.05 | 2.5 | 0.38 |
| 半独立型 | 3.0 | 1.12 | 2.5 | 0.35 |
| 嵌入型 | 3.6 | 1.20 | 2.5 | 0.32 |
* 基本COCOMO模型适用于项目初期、快速粗略地进行软件估算:
没有考虑到对软件工作量有影响的某些项目属性,比如,不同的硬件条件、人员素质及经验、对现代工具与技术的使用等方面,所以该模型的准确程度有限。
中级COCOMO模型
* 该模型以基本COCOMO模型为基础,除考虑源代码行数之外,还使用一个工作量调节因子EAF进行修正,其估算公式如下:$E=a_{2} \times L^{b_{2}} \times E A F$
$E$——工作量(单位:人月)
$L$——估计的代码行数(单位:KLOC)
* $a_2$是模型系数,$b_2$是模型指数,均为常数,其值与软件项目的类型有关,中级COCOMO模型系数表如下:
| 类型 | $a_2$ | $b_2$ |
| -------- | ----- | ----- |
| 组织型 | 3.2 | 1.05 |
| 半独立型 | 3.0 | 1.12 |
| 嵌入型 | 2.8 | 1.20 |
* 通过对影响软件工作量的17个因素进行评估,从而确定调节因子EAF:$\begin{align}E A F=\prod_{i=1}^{17} F_{i}\end{align}$
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-04-55-7421d844a705df5dee280acdaa8821fc-upload_e497b219799f20400ad5a5cf086cd284-99f888.png)
### 2.2.3 软件成本/效益分析
目的:从经济角度分析评价开发一个新的软件项目是否可行(是否值得开发),即分析软件项目的经济可行性
成本/效益分析的方法
* 货币的时间价值
假设年利率为$i$,投资额$P$在$n$年后的价值$F$为
$F=P(1+i)^{n}$
类似的,预计$n$年后所产生的效益$R$折合成现在价值$S$为
$S=R /(1+i)^{n}$
* 投资回收期
投资回收期是指软件项目累计的经济效益等于最初投资成本时所需要的时间
投资回收期越短,说明利润获取越快,软件项目越值得投资
* 纯收入
纯收入是指在软件的使用寿命期内累计产生的经济效益(折合成现在价值)与投资成本之差
### 2.2.4 小结
* 由于软件项目中变化和影响的因素太多,所以导致软件项目的估算从未达到精确
* 存在很多估算技术和估算模型,它们采用的计算公式,考虑的因素,复杂程度都各有不同
* 大多数估算模型都是根据某些应用领域中有限个实际项目的经验数据总结出来的,因此,适用范围有限(没有一个估算模型可以适用于所有类型的软件)
* 具体应用时,要根据当前软件项目的特点选择适合的估算模型,并对其进行适当修正(比如,调整模型常数)
## 2.3 软件项目进度管理
在项目规划阶段,一个非常重要的管理活动就是制定出合理的项目进度计划,进度安排的好坏将直接影响到整个项目能否按期完成
软件项目进度管理中常用的两种图形工具:
* 甘特图(Gantt Chart)
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-05-05-911dde018ad2e5fb09c11283b0fe7620-upload_d9965b720aacca37a468b8cd9e7dc880-e5d2a0.png =500x)
* 用法:
横轴:表示时间
纵轴:表示项目中所安排的各个活动(或任务)
水平线段:表示对某个活动(或任务)的进度规划
线段起点对应横轴上的时间表示活动的开始时间
线段终点对应横轴上的时间表示活动的结束时间
线段长度表示活动的持续时间(即预计完成该活动所需要的时间)
* 优点:
简明直观,能清晰描述出每个活动何时开始,何时结束,持续多长时间,以及某些活动之间的并行性
* 缺点
不能显式地描绘出各项活动之间的依赖关系
进度计划中的关键部分不明确
进度计划中有潜力(时间灵活,有松弛度的)的部分以及潜力的大小不明确
* 工程网络图(也称CPM(Critical Path Method),即关键路径法)
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-05-17-2c6b7f257d7e77501d1285d02f70d8a3-upload_cf12b53f40be1921ba679f1f4f4f17cb-51376f.png =500x)
* 用法
* 工程网络图是一个有向图
* 时间节点
* 最早开始时刻EET
* 最晚开始时刻LET
* 连接两个时间结点之间的箭头直线代表任务,任务箭头上标有**完成该任务预计所需要的时间**(即该任务的持续时间),以及**该任务的机动时间**(即松弛时间)
* 最早开始时刻EET计算方法
* 从左向右顺着任务流的方向
* 最晚开始时刻LET计算方法
* 从右向左逆着任务流的方向
* 关键路径
* 工程网络图中消耗时间最长的路径,即任务的持续时间累加之和最大的那条路径
* **在关键路径上出现的时间节点满足EET=LET**
* 关键路径上的所有任务的持续时间之和为工程项目的总工期
* 机动时间
* 不在关键路径上的任务(即非关键任务)都有一定程度的机动时间
* 机动时间=LET-EET-持续时间
## 2.4 软件项目风险管理
软件风险管理:通过主动而系统地对项目风险进行全过程的**识别、分析与监控**,最大限度地降低风险对软件开发的影响。
1. 风险识别
识别项目中有哪些已知的和可预测的风险。通过分析项目风险产生的各种原因,以确定风险事件及其来源。
常用方法:建立“风险条目检查表”(自问自答,自主评估)
常见的软件风险
* 软件规模风险
* 客户相关风险
* 商业影响风险
* 软件过程风险
* 开发环境风险
* 开发人员风险
* 开发技术风险
2. 风险评估
对已识别的软件风险进行估计和评价,两个方面:
* 估计风险发生的可能性或概率
* 估计风险发生所带来后果的严重程度
风险度量
* 一般从性能、成本、进度等方面考虑风险对项目所产生的影响
* 产生的影响一般被划分为4个级别:可忽略的$\rightarrow$轻微的$\rightarrow$严重的$\rightarrow$灾难性的
风险评估表
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-05-42-73be61f2d10fbfa4b9be0e8de282c16a-upload_f27f8cc29934371633fc2e31db2cd842-f9746c.png =500x)
3. 风险规划
制定具体的风险应对策略,以处理项目风险
* 规避风险:主动采取措施避免风险,降低风险发生的可能性
* 接受并缓解风险:采取应急方案应对风险的发生,减少风险产生的影响
* 转移风险:将风险转移给第三方
* 风险自留:当风险量不大时可以余留风险
4. 风险监控
贯穿于软件开发的全过程,是一种项目跟踪活动
* 对风险事件的发生情况及其来源(风险源)进行监控
* 监督并检查在项目实施过程中风险措施的落实情况,以确保风险措施的有效
# 3 需求工程
## 3.1 软件需求
软件项目开发的一个关键目标是:软件要能够满足客户的需求
1. 软件需求的定义
以**清晰、简洁、一致且无二义性**的方式,描述用户对目标软件系统在功能、行为、性能、设计约束等方面的期望,是在开发过程中对软件系统的约束。
软件需求常用于表达“目标系统要做什么,做到什么程度”,而不是去描述“如何做”。
2. 软件需求的分类
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-06-04-0f708e3a5d48e391726496d882a8753f-upload_75ff94e4844d55020e9057ea9f63addf-ed0c48.png =450x)
1. 业务需求(Business Reqs)
是客户对于软件系统的高层次目标要求,定义了项目的远景和范围。一般可能包括(主要是一些提纲挈领性的要求):
* 业务:属于哪类业务范畴?为何目的?
* 客户:软件为谁服务?目标客户是谁?
* 特性:区别于其他竞争产品的特性是什么?
* 价值:价值体现在哪些方面?
例:“图书资料管理系统”的业务需求(*相对抽象*)实例:
* 该系统使用计算机实现图书资料的日常管理,提高工作效率和服务质量
* 该系统可让用户在网络上查询与浏览电子资料,改变原有的借阅模式
2. 用户需求(User Reqs)
从用户角度描述软件系统的功能需求与非功能需求,通常只涉及**系统的外部行为**而不涉及内部特性。
例:“图书资料管理系统”的用户需求(*相对具体*)实例:
* **用户可以**通过Internet随时查询图书信息
* **用户可以**通过Internet随时查询个人借阅情况
* **用户可以**通过Internet快速查找和浏览电子资料
3. 功能需求(Functional Reqs)
描述软件系统应该提供的功能或服务,通常涉及**用户或其它外部系统与目标系统之间的交互**,**不考虑目标系统内部的实现细节**
例:“图书资料管理系统”的功能需求实例:
* 用户可从图书资料库中查询或者选择其中一个子集
* 系统可提供适当的浏览器供用户阅读馆藏文献
* 用户每次借阅图书应对应一个唯一的标识号,它被记录到用户的账户上
4. 非功能需求(Non-Functional Reqs)
即性能需求,反映了客户对软件系统质量和性能的额外要求。比如:响应时间、数据精度、可靠性、可用性、安全性等
由于NFR的定性描述难以检验,通常会转而采用一些可度量的特性
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-06-21-5e1c0de394cd5a5609db2ffb333b72be-upload_9f8eed6f64ec9105148af10217d1a07e-6d39b1.png =400x)
例:“图书资料管理系统”的非功能需求实例:
* 系统在**20秒内响应所有的请求**
* 系统应该**每周7天、每天24小时都可使用**
* 对一个没有经验的用户而言,经过**2小时培训即可使用**系统的所有功能
5. 约束条件(Cons)
软件系统设计和实现时**必须满足的限制条件**
例:约束条件实例:
* 系统必须用C++或其他面向对象语言编写
* 系统用户接口需要采用图形化界面
* 系统开发过程和交付文档需遵循GB/T 8567-2006标准
6. 业务规则(Business Rule)
对某些功能的可执行性或内部执行逻辑的一些限定条件
* 限定条件来自于用户的实际应用场景
* 通常表达为“如果...,那么...”的形式
例:业务规则实例:
* 如果借书卡类型为“教师”,那么一次借阅的最大数量为8本
* 如果订单金额大于10000元,那么该订单的折扣为10%
* 如果采购单金额在10万到50万之间,那么需要总经理审批
* 如果开具了药品A,并且病人年龄在65岁以上或12岁以下,其总剂量不能超过20片
7. 外部接口需求(External Interface)
描述目标系统与外部环境之间的交互接口
* 用户接口
* 硬件接口
* 软件接口
例:外部接口需求示例
* 从<某些设备>读取信号
* 给<一些其它系统>发送消息
* 以<某种格式>读取文件
* 能控制<一些硬件>
* 采用<某种类型的>用户界面
8. 数据定义
由用户描述一个数据项或一个复杂的业务数据结构的格式或缺省值
例:数据定义示例
* 邮政编码由5个数字组成,后跟一个可选的短划线或一个可选的四位数字,缺省为0000。
## 3.2 需求工程过程
需求工程是软件工程的一个主要分支
是应用已证实有效的原理和方法,帮助分析人员理解问题,确定软件需求,定义目标系统的所有外部特征和相关约束,**形成需求文档**,并对用户不断变化的需求演进给予支持
它是一个不断进行需求定义、记录和演进的过程
需求工程过程主要包括以下基本活动
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-06-35-5fff82b81dbb9130bb64b6c2562d7aa2-upload_6895a091396262c67aa0ab1c3e15d9aa-0d1d6a.png =520x)
1. 需求获取
* 通过与用户的交流以及对现有系统的观察分析,从而**开发、捕获和修订用户的需求**
* 主要内容包括
* 对用户进行分类
* 聆听每一类用户的需求
* 分析和整理所获取的需求信息
* 形成文档化的描述
2. 需求分析
* 对收集到的需求进行提炼、分析,为最终用户所看到的软件系统**建立概念化(只考虑系统外部特征,不考虑系统内部实现细节)的分析模型**
* 主要内容包括
* 定义目标系统的边界
* 建立软件原型
* 分析需求实现的可行性(**确定与需求实现相关的开发风险**)
* 确定需求优先级(按增量模型,确定不同增量之间的优先级,**有助于软件版本的规划**)
* **建立分析模型(结构化分析方法和面向对象分析方法)**
* 创建数据字典
3. 需求规格说明
* 将需求开发的结果按照规定格式用文档形式进行描述,即**撰写软件需求规格说明书(SRS)**
* SRS中**应包含**的内容有:
* **功能**:该软件系统能够向用户提供何种服务?
* **外部接口**:该软件系统如何与用户、硬件、其他软件系统进行交互?
* **性能**(非功能属性):软件系统在运行速度、可用性、可移植性、安全性、可靠性、可维护性等方面有哪些特殊要求?
* **约束条件**:是否存在必要的标准、编程语言、运行环境、资源等约束限制?
* SRS中**不应包含**的内容有:
* 项目开发计划:比如成本、人员、进度等。
* 产品保证计划:比如配置管理、验证与测试、质量保证等。
* 软件设计细节:需求通常用于表达“做什么”,而不描述“如何做”。
4. 需求验证
* 通过评审方式,验证需求规格说明的有效性,以发现其中存在的错误或缺陷,并由开发人员及时更改和补充,修改后的需求规格说明还要进行再评审,直到通过为止
* 需求验证主要围绕SRS的以下质量特性展开审查:
* 正确性
SRS对系统功能、行为、性能等的描述**必须与用户的期望相吻合**
* 无二义性
SRS中的描述对于所有人都只能有**一种明确统一的解释**
专业术语表、名词或术语定义、可量化或可验证
* 完整性
SRS应该包含软件系统要完成的全部任务,不能遗漏任何必要的需求信息
* 可验证性
**SRS中描述的任何一项需求都可以运用一些可行的手段对其进行验证**,证明其是否在最终的软件系统中得到满足
SRS中不应存在一些不可验证(很快,很好,友善,容易...)的描述。所有的需求描述都应是具体的和可度量的
* 一致性
SRS中对各种需求的描述不能存在矛盾
* 可修改性
SRS应该具有良好的格式和文档组织结构,以保证后续的修改比较容易进行
* 可跟踪性
SRS中的每项需求都能与它的来源、设计元素、源代码、测试用例等联系起来
* 前溯:每一项需求都可以在早期文档中追溯到其来源
* 后溯:每一项需求都有唯一的索引号,可以与后期的设计方案、实现结果、测试用例相对应
5. 需求管理
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-06-52-31036f93e212a9a35e46f2d9688f794c-upload_fb1831bcb746105c3f2def4218ed8219-9c658c.png =600x)
需求管理是在需求基线形成之后有效地控制需求变更的过程,以处理不断变化的需求约定
主要包括以下活动:
* 需求变更控制
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-07-05-4642cae40ec2913de78fd5fe4e6dc2e3-upload_d58d9261707440bf064142ae7f767f5b-9c85e6.png =600x)
* 需求版本控制
每一个已公布的需求文档版本都应该具备一个修正版本的历史记录,包括:
* 变更内容
* 变更日期
* 变更人姓名
* 变更原因
* 需求跟踪
当某项需求发生变化时,可能会影响到其它需求的变化,并且连带地影响到设计、实现、测试、项目计划等各方面的变化(*波纹效应*),从而构成一个需求跟踪能力联系链
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-07-20-87691b5db4d0916dcbaa096b3a7a4825-upload_a1afc7c34968aea099734434d08c2a69-11878e.png =600x)
一个需求跟踪能力矩阵示例:
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-07-33-d71f650ab0baa9725d14a1d180ee0067-upload_de10499b1ba79f7f52ede2f33e2141cd-98b31f.png =500x)
## 3.3 需求获取技术
1. 需求获取的基本步骤
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-07-44-85d1bb1ab23f3387c797d3a5e5eebe1c-upload_7ce33180e91dd23f47fc86feafea5fbf-bcc760.png =500x)
2. 需求获取过程中可能遇到的问题
1. Yes, But 现象
* 表现:不管之前用户多么认同你的设计,在没有看到真正的系统之前,客户决不可能完全理解你的设计
* 应对:在软件开发中,需求获取阶段的一个重要目标就是如何尽早的把“But”后面的需求部分发现并挖掘出来
2. Undiscovered Ruins 现象
* 表现:随着对用户领域的不断了解,和用户之间的交流逐渐加深,需求就会随之不断膨胀。无法判断尚未发现的需求还有多少(用户自己可能也不是一开始就有清晰的需求)
* 应对:需求是永无止境的。不可能指望一次性地从用户那里把所有需求都获得到。应当将用户当做领域专家来认识和激励,启发用户尽可能详细与全面地思考描述需求
3. User and Developer 现象
* 表现:开发人员和用户存在不同的技术层面,沟通存在交流鸿沟,无法充分地相互理解
* 应对:换位思考,试图将开发人员扮演成用户的角色
3. 需求获取技术
* **需求获取的关键:沟通和交流**
* 可能的方法:
1. 面对面访谈
* 是需求获取中最简单直接的方法
* 面谈对象包括用户和领域专家
* 专业术语存在理解障碍,彼此可能造成需求无解
* 所处环境不同,一些用户习以为常的需求可能会被忽略
2. 需求讨论会
* 通过开发方和客户方召开若干次需求讨论会议,达到弄清项目需求的目的
* 会议方法有助于参会者**尽快**在需求上达成共识、对操作过程取得统一意见
3. 现场观察/体验
* 有时用户可能无法有效全面的表达自己的需求,通过面谈或会议的方式也难以获得完整的需求信息。在这种情况下,**系统分析员现场观察用户的工作流程有助于全面深入了解用户需求**
* 被动观察:用户实地工作,分析人员在旁边观察用户的业务活动
* 主动体验:分析人员直接参与到用户的实际工作中,与用户一起进行业务活动
## 3.4 结构化分析方法
在需求分析中,用于建立目标系统分析模型的一种传统方法。该方法采用图形化方式,分别从数据、功能、行为三个不同角度表达用户需求
结构化分析模型的组成
1. 数据模型
2. 功能模型
3. 行为模型
4. 数据字典
* 数据建模
* 基本思想
* 从用户视角建立一个概念性的数据模型,也称信息模型
* **该数据模型与系统实现无关**。主要描述用户角度所看到的目标系统中有哪些数据对象,数据对象自身有哪些属性特征,以及各个数据对象之间有何联系
* 实体关系图(Entity Relation Diagram)
实体之间构成关系,并且关系与实体都具有其属性
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-07-55-45bf7412dbfc5796ec0204803daeed90-upload_12affc1da3d2f8341ab29586287daf29-828f09.png =400x)
* 实体(矩形)
* 属性(椭圆)
* 关系(菱形)
* 功能建模
* 基本思想
* 从目标系统内部的数据流出发,按照自顶向下逐层分解的方式,定义出目标系统的所有逻辑功能。
* **功能建模只反映目标系统的逻辑功能,不反映功能的具体实现**
* 数据流图(Data Flow Diagram,DFD)
描绘数据信息在目标系统内部的各个逻辑功能之间传递,变换的过程
* 外部实体
代表目标系统的外部环境,包括系统用户(人员或组织)、与系统连接的其它硬件设备或软件系统
**数据源点或数据终点**
* 数据加工
**是数据流图的核心**。它表示目标系统中对数据信息所进行的某种操作或变换,输入的数据流经过某个 “加工”后产生输出的数据流
* 数据存储
代表目标系统内部需要保存的数据,以某种数据组织形式存在
* 数据流
代表目标系统内部传递变换的数据信息及其流向
* 数据流图的层次性——分层数据流图
* ![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-08-07-ffc39db172e7982579d23f7745d217fc-upload_92167c1db123b7b8d1a176e49e5321d1-12f490.png =500x)
* 顶层DFD
**通过目标系统与外部环境之间的联系,来表明目标系统的边界**
通常只包含**一个**“数据加工”,用以抽象地表示整个目标系统,然后考虑目标系统有哪些输入数据流和输出数据流
* 中间层DFD
是从抽象到具体的一系列过渡层
某一中间层DFD是对其上一层父图中的某些“数据加工”进行分解,然后考虑分解后的各个“子加工”之间可能出现的数据流,从而形成的一个子图
* 底层DFD
底层DFD中的每一个“数据加工”都**不能或不需再分解**,称其为“基本加工”
* **注意事项**
* 父图与子图的平衡:一个数据流子图必须与它上一层父图中的某个“数据加工”相对应,并且该子图的输入/输出数据流要与父图中所对应的“数据加工”的输入/输出数据流必须一致
* 例:
某医院打算开发一个以计算机为中心的患者监护系统。医院对该系统的基本功能要求如下,试画出该患者监护系统的数据流图
* 各种病症监视器安置在每个病床旁,将病人的组合生理信号(比如由脉搏、血压、体温等组成)实时地传送到中央监护系统中
* 值班护士通过中央监护系统对病人情况进行监控,监护系统实时地将病人的生理信号与正常生理信号的安全范围进行比较分析
* 当病人出现异常时(即病人的生理信号超出安全范围时),系统将自动报警
* 系统可以定期自动记录病人情况以形成患者日志;此外,护士在需要的时候还可以要求系统打印某个病人的病情报告
**Step1:从以上问题描述中提取数据流图的四种基本元素**
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-08-20-a275a50cd85b52bdcb92f628b5d2b5ab-upload_25c6e7e342cceae50404b03bac4eda7b-8e8587.png =450x)
**Step2:绘制顶层数据流图(第0层DFD)**
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-08-28-cf57eaf7336e4edc20794ef5c7f72a0f-upload_d3d1a04d046eba457f7ab8a831ae876c-d9f00c.png =450x)
**Step3:细化顶层数据流图,绘制第1层DFD**
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-08-40-0a4ab062dd7928eeab5881ac4b99def1-upload_6a1bbb490bb118252d4652f6cafc9e0b-61bd75.png =450x)
* 行为模型
* 基本思想
通过分析目标系统在运行过程中可能存在的**各种状态**,以及引起这些状态之间发生转换的**外部事件**,从而来表示**系统的动态行为**
* 状态转换图(State Transform Diagram, STD)
* 状态
* 代表目标系统向外展示出来的,可被外界用户观察到的某种行为模式
* 它反映了系统对外部事件的响应方式
* 分为三种类型:
* 初态(初始状态):只有一个
* 中间状态:可以有多个
* 终态(最终状态):可以有多个或没有
* 外部事件
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-09-15-58250326f8c3772b7ae4dab28457e82c-upload_be0cf6b83c0ad66421646870fad1d49e-cdc27b.png)
* 事件表达式
* ``事件名[守卫条件]``
* | | | 转移情况 | 转移结果 |
| --- | --- | ------------------------ | -------------------------------------------- |
| | | 事件名和守卫条件同时出现 | 当事件发生并且守卫条件也为真,则发生状态转换 |
| | | 只有事件名,没有守卫条件 | 只要事件发生,则发生状态转换 |
| | | 只有守卫条件,没有事件名 | 只要守卫条件为真,则发生状态转换 |
* 例
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-09-26-62d9a1330ed65c491afab9f7ce56b45a-upload_7337db9523d8966b267a5fc8c027fb00-93d685.png =500x)
* 数据字典
* 主要作用
数字字典是对数据流图中出现的**各种元素(包括数据流、数据存储、数据加工)**分别以词条的形式进行定义和描述,使得**每个元素都有一个确切的解释**
数据字典是对数据流图的补充,两者相互配合
* 具体内容
* 数据流词条
* 数据流名称
要求与数据流图中出现的名称一致
* 描述
简要介绍该数据流在系统中的作用
* 数据流来源
该数据流来自哪里(数据加工或外部实体)
* 数据流去向
该数据流流向哪里
* 数据流的组成(定义)
描述该数据流的数据结构
* 数据存储词条
* 数据存储名称
要求与数据流图中出现的名称一致
* 编号
该数据存储在数据流图中的编号
* 描述
简要介绍该数据存储存放的是什么数据
* 数据存储的组成(定义)
描述该数据存储的数据结构
* 数据存储方式
索引文件/数据库表
* 数据项词条:数据存储或数据流中所包含的数据项
* 数据项名称
* 描述
简要介绍该数据项的含义
* 数据项的类型
字符型、数值型、布尔型等
* 数据项的长度(或精度)
比如,数据项“身份证号”的长度18位
* 数据项的取值范围
比如,数据项“职工年龄”的取值范围定义为18岁至60岁,表示为``18..60``
* 数据项的缺省值
比如,定义数据项“借书日期”的初始值默认为系统的当前日期
* 数据项的组成(定义)
描述该数据项的相关数据元素及数据结构
* 基本数据加工词条:最底层的数据加工
* 加工名称
要求与数据流图中出现的名称一致
* 加工编号
要求与数据流图中出现的编号一致
* 描述
简要介绍该加工的处理功能
* 输入
指明该加工的输入数据流
* 输出
指明该加工的输出数据流
* 加工逻辑
简述该数据加工的处理逻辑(此项描述也可以单独形成一份“加工逻辑说明”,关于加工逻辑的描述方式主要有PDL语言、判定表或判定树等)
* 定义方式
* 基本思想
对数据自顶向下分解
* 四种方式
* 顺序
* 选择
* 重复
* 可选
* 常用符号
| | 符号 | 含义 | 解释 |
| --- | --------------- | ------------ | ------------------------------------- |
| | $=$ | 被定义为 | |
| | $+$ | 与 | $x=a+b$,$x$由$a$和$b$组成 |
| | $[...\mid ...]$ | 或 | $x=[a\mid b]$,$x$由$a$或$b$组成 |
| | $\{...\}$ | 重复 | $x=\{a\}$,$x$由0个或多个$a$组成 |
| | $m\{...\}n$ | 重复 | $x=3\{a\}8$,$x$由$[3,8]$个$a$组成 |
| | $(...)$ | 可选 | $x=(a)$,$a$可在$x$中出现也可以不出现 |
| | $"..."$ | 基本数据元素 | $x="a"$,$x$为取值为$a$的数据元素 |
| | $..$ | 连结符 | $x=1..9$ ,$x$可取$[1,9]$内的任一值 |
* 例
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-09-41-f0bd909f69028c3bc565e2023b62724a-upload_e1aaa36098f623772755c73f6c365386-807e44.png)
```
存折 = 户名+开户行号+账号+开户日期+性质+(印密)+1{存取行}20
户名 = 2{汉字}4
开户行号 = "001".."999"
账号 = "00000001”.."99999999"
开户日期 = 年+月+日
性质 = "1".."6"
印密 = “0”
存取行 = 日期+(摘要)+支出+存入+余额+操作+复核
```
# 4 软件设计
## 4.1 软件设计概述
软件设计:为问题域的外部可见行为的规约,增添计算机系统实现所需要的细节,包括关于人机交互,任务管理和数据管理等细节
1. 软件系统结构设计
* 确定软件系统的结构,即软件系统的组成,以及各组成成分(子系统或模块)之间的项目关系
* 主要包括
* 选择合适的软件体系结构**风格**
* 基于功能层次建立系统
2. 接口设计
* 确定目标系统与其他软硬件系统之间,目标系统与用户之间的相互关系及通信方式
* 主要包括
* 用户界面设计:支持目标系统与用户之间的通讯
* 通讯结构设计:支持目标系统与其他软硬件系统之间的通讯
3. 数据设计
* 侧重数据结构的设计
* 主要包括
* 对需要永久存储的数据文件和数据库的设计
* 结合算法设计对算法内部的逻辑数据结构及其操作进行设计
4. 过程设计
* 过每个模块内部的执行逻辑转成过程性描述
* 主要包括
* 确定各个模块内部的实现算法,以及各个模块内部的数据组织
* 选择
与需求分析模型之间的映射关系:
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-09-50-2aebd231682ab2306434a27078fbd43f-upload_47487774ea53c4069279948ea73da56b-dece31.jpeg)
软件设计的两大阶段:(自顶向下,逐步细化)
* **概要设计阶段**
* **体系结构设计**
* **详细设计阶段**
* **数据设计**
* **过程设计**
## 4.2 软件体系结构的典型风格
软件体系结构风格通常需要有的部分:
* 一组预定义的模块
* 不同软件模块的职责
* 组织和管理模块的规则
软件体系结构设计是**概要设计阶段的主要任务**,它**只侧重于系统宏观结构的设计,而不关心内部算法**
典型风格:
* 主程序-子过程风格
* 结构化程序设计的一种典型风格,通过**自顶向下逐步分解和细化**的方法,得到系统的体系结构
* 本质:将系统分解为若干模块,主程序调用这些模块实现完整的程序功能
* 构件:主程序、子程序
* 连接器:调用-返回机制(remote procedure call, RPC)
* 拓扑结构:树状结构
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-10-06-72dc051cc2786d6c08a990a0b417a098-upload_3122eb77022c0451d36f7a63799e9b5b-ab0d18.png =300x)
* 面向对象风格
* 系统被看做对象的集合(后续详述)
* 构件:对象
* 连接器:消息传递机制
* 拓扑结构:网状结构
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-10-17-c572173c23e0069972e2669eb60c2dcf-upload_6f744d3181af6185fb0002f2e5eae484-aa8bdc.png =300x)
* 层次风格
* 层次化已经成为一种**复杂系统设计的普遍性原则**
* 在层次体系结构,整个系统被组成若干个层次,形成一个分层结构。每个层次都由一系列构建组成
* 层次之间形成call-return的关系:每一层为上层提供服务,并且利用下层的服务
* 不同的层次处于不同的抽象级别:**越靠近底层,通用性越强**;**越靠近顶层,专用性越强**
* 典型应用:OSI网络模型
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-10-28-c416406e57c2c7fb679c6c587a4e8d9c-upload_d3b1008b37bde938f078ee0d91955d66-86b541.png =300x)
* 严格分层与松散分层(补)
* 严格分层系统:要求严格遵循分层原则,限制某层中的构件只能与它紧邻的下面一层进行交互
* 松散分层系统:放宽了此限制,它允许某层中的构件与位于它下面的任意一层中的构件进行交互
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-10-37-15e9891b091740d149ccd1e7162519ce-upload_59300da1cd1278aa10733049237efe9e-afef1e.png =500x)
* 以数据为中心的风格(仓库风格)
* 中央数据仓库(比如,文件或数据库等数据存储形式),位于体系结构的中心
* 一组相互独立的子系统(或模块),需要经常访问数据仓库,共享数据仓库中的数据。形如通常为星型结构
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-10-47-efee0bc5d443856131b5c89fca6fd4c7-upload_c873415b9aed0a310309d465089e9605-8eb880.png =300x)
* 典型应用:注册表,剪贴板
* 客户机-服务器体系结构
* 客户机-服务器结构(简称C/S结构)是一种典型的分布式体系结构
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-10-57-af6fe7e82f3d55d4c8a4b36cabc6d860-upload_5f7bc686634ea02c24b504925e70bf74-f93a76.png =400x)
* C/S结构的层次性
* 用户界面部分:即表示层,主要实现用户与应用系统之间的交互接口,用于接收用户输入的数据,并显示应用系统输出的数据
* 应用逻辑部分:即业务逻辑层(或功能层),主要实现应用系统的各种处理功能
* 数据管理部分:即数据层,主要实现数据的存储以及对数据的存取访问等操作
* 两层C/S
* 瘦客户机/胖服务器
客户机所具有的处理能力在该模型中得不到充分的发挥
* 胖客户机/瘦服务器
能够利用客户机的处理能力,比瘦客户端结构在分布处理上更有效。但却使系统的维护和升级比较困难
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-11-08-d0a847b00aba17e95afcf5c667bfaeed-upload_ac6c0bc95eb683d63d0baa7f323ffd4f-274cbd.png =400x)
* 三层C/S
* 更加体现分布式特点
* B/S
* 是三层C/S风格的一种实现方式,其具体结构为浏览器/Web服务器/数据库服务器
* 基于B/S结构的软件系统,安装、修改和维护全在服务器端解决,系统维护成本低(真正达到了"零客户端")
* **良好的灵活性和可扩展性(各层,各部分独立;松耦合)**,当系统环境和应用条件发生变化时,只要对业务逻辑层实施相应的改变,就能够达到目的
* 基于集群的分布
1. **冗余**模式:$Server_1=...=Server_n=Data_{full}$即每一层都是完整的数据层/业务逻辑层,以提高系统的可用性与可靠性
2. **并发**模式:$Server_1+...+Server_n=Data_{full}$即每一层之和以共同构成完整的数据层/业务逻辑层,以提高系统的并发处理能力,改善系统的运行速度
## 4.3 结构化设计方法(Structure Design,SD)
一种面向数据流的设计方法
* 根据数据流图(DFD)的不同类型,将其转换为相应的软件体系结构(属于*主程序-子过程*风格)。
目标:通过对模块的合理划分,得到软件的体系结构图,进而再细化每个模块内部的处理流程
采用的主要描述工具:
* 结构图(Structure Chart,SC)
* 程序流程图等过程描述工具
核心原则——模块化
* 模块化:将软件系统划分为若干个模块
* 每个模块完成一个**相对独立的子功能**
* 每个模块定义各自的输入和输出
* 若干个模块集成在一起,形成整体,完成系统的全部功能(模块和模块之间的连接关系)
* 是一种分而治之的设计策略
* 将复杂问题分解为小问题
* 模块化设计的优点
* 通过模块分解可降低系统复杂性,提高复用度(模块复用),使系统易于修改和维护
* 有助于系统各部分之间的并行开发,提高软件开发效率
* 模块具体可以指:
* 是数据说明和可执行语句等程序对象的集合。比如,结构化程序设计中的过程、函数、子程序等都可视为模块
* 模块的基本属性
* 功能:描述模块实现什么功能(外部特性)
* 接口:描述模块的输入和输出(外部特性)
* 逻辑:描述模块内部的具体执行过程(内部特性)
* **一个模块的内部特性对于其他模块来说应该是隐蔽的——"信息隐蔽"原则**
* **模块的独立性**
模块独立性是软件系统划分模块时的一个主要准则
* 内聚性
* 从**功能**的角度来衡量模块内部的联系
* 如果一个模块内部的所有成分,都是为了完成某个单一功能,而彼此紧密结合在一起,则说明该模块的内聚性强
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-11-20-30402951c1b837c6e412cc07f1834cb8-upload_03fe6868a1b652a9b0d6b6c47b85a5fa-98d51d.png =400x)
* 逻辑内聚
* 一个模块内部可能包含多个处理任务,当它被调用时,由其它模块传进来的控制参数来决定应执行其内部的哪个任务
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-11-30-8fa96538fbfcef5d6e784efc42ee585b-upload_1e129bad9b7f139591bdbef7d328f03a-1473d0.png =400x)
* 时间内聚
* 因为必须要在同一时间内执行一系列任务的原因才把这些处理任务联系到一起
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-11-40-bd05719535a9627eb158cc3409249ab4-upload_dd380f15f9865885b5bfb2558ad3d235-9bd254.png =400x)
* 顺序内聚
* 一个模块内部可能包含多个处理任务,这些任务按顺序执行,形成操作序列,而且**前一个任务的输出是下一个任务的输入**
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-11-49-37091412bf2b80c97614bd1fc8d553b1-upload_36f6ef5eda10a36c4136c04e6a25b49e-b6ce7f.png =230x)
* 功能内聚
* 模块内部的所有成分都是为了完成一项单一的功能(或任务)而紧密联系在一起,协同工作,**不可分割**
* 这种模块通常只完成一个功能或任务,粒度最小,几乎不可分割,如:
* 功能内聚模块A:根据输入的角度计算其正弦值
* 功能内聚模块B:求一个组数中的最大值
* 耦合性
* 表示模块与模块之间相互联系、相互依赖的紧密程度
* **模块间连接越紧密,联系越复杂,耦合性越高**
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-12-47-ef1219f5cfe282238911651be6fef30c-upload_a31fa6f49acf11df4822c78488164953-2bdc53.png =350x)
* 公共耦合
* 两个模块是通过访问同一个公共数据环境(比如,全局数据项、全局数据结构、共享的通信区等)而产生的相互联系
* 公共数据环境的变化,将影响**所有公共耦合模块**,使模块的**可修改性(不利于错误的定位)、可靠性和可维护性下降**
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-12-56-8f8430adf5f78332fc9da7730303d418-upload_d0b4f0c0f3dfa919313b94e7ae66782a-059cc8.png =440x)
* 控制耦合
* 一个模块是通过传递控制信息,来控制另一个模块内部的执行逻辑的联系方式
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-13-05-59c8ee9203b0c0c0fb55c08272022eb4-upload_14194f3f7c6eb05c57dccafb624d9d0c-073c31.png =490x)
* 标记耦合
* 如果两个模块之间传递的信息是**一个复杂的数据结构**(比如,数组、结构体等),而不是简单类型的变量(数据耦合),则它们之间的耦合称为**标记耦合**
* 数据耦合
* 如果两个模块之间是通过传递一些**简单的数据项**来交换输入、输出信息,则它们之间的耦合称为**数据耦合**
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-13-15-be105600c415adffe7da94b8b85d24bb-upload_a5a849d596d60fae7dac4e31877983e5-8c8aa4.png =380x)
* 小结
* 模块内部联系紧密,模块功能单一,则模块本身的内聚性越高,模块的独立性越强
* 模块之间联系紧密,模块之间的接口复杂,则模块之间的耦合性越高,而模块的独立性越弱
* **模块化设计的目标:高内聚,低耦合(即提高模块内部的联系,降低模块之间的联系)**
结构图(Structure Chart,SC)
* 基本元素及符号表示
* 模块
实现特定功能,有明确的输入,内部处理逻辑和输出。一般用**矩形框**表示
* 调用关系
模块之间通过过程/函数调用的方式建立连接,一般用自上而下的箭头的连线表示调用关系(是上层模块调用下层模块)
* 信息传递
模块调用过程中所相互传递的信息
* 数据信息:业务性数据,通常为简单或复杂的数据类型
* 控制信息:相互调用时所传递的标记性数据
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-13-27-fb67623ecf539104f46a1fc99c858445-upload_7ecdfbb391aecf7daeee27edba981599-afead7.png =500x)
* 模块调用形式
* 简单调用![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-13-42-ad3d8b2abc35f51832ed20b978b15e8d-upload_1487b04acdc69473b578878de3c854d6-1a290b.png =150x)
* 选择调用![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-14-08-e25294e2393e33c91dd078fa090ef2f5-upload_de3b6fd8f80f3b102bb5ab2a60f631f8-409c7d.png =380x)
* 循环调用![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-14-21-f1681cbc531cfa488d106d552aa28a61-upload_ca7ad9bbe138228f121600d430195666-bc3867.png =380x)
* 形态特征
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-14-31-e0a8777942f082720912b297746ac210-upload_bbefa98049d63b0692270e69f90b993b-b46063.png =500x)
* **DFD图与SC图的映射**
根据DFD的类型(变换型/事务型)分别映射成(变换型/事务型)的SC,之后再**进行优化调整**
* 变换型DFD
* 主要特征
信息沿着输入路径进入系统,同时由外部形式变换为内部形式,然后经过系统内部的 “变换中心”进行处理,处理后的结果再沿着输出路径变换成外部形式离开系统
输入部分与变换中心之间,变换中心与输出部分之间都具有较为明显的边界
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-14-42-6b4d22a63f002c0ed9579d2517240663-upload_360478c99e23c7d6b65aad08333dcc0b-6acae2.png =400x)
* 变换分析
1. 在变换型DFD中,找出输入、变换中心和输出三部分,并标出分界线。即确定输入流和输出流的边界,从而分离出变换中心
2. 进行第一级映射,即确定变换型SC中的顶层(主模块$M_C$)和第一层结构(输入信息处理模块$M_A$;变换中心控制模块$M_T$;输出信息处理模块$M_E$)
3. 进行第二级映射,即在第一级映射的结果上,将DFD中的每个数据加工按照一定规则,映射成为SC中的一个模块,直至画出每个分支上所需要的全部模块为止
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-14-55-1fa604f96c4a6098dd50e6c9bfcd868b-upload_45a38d9e0d9f1fd0ae4a69800d19fb32-a60864.png =500x)
* 事务型DFD
* 主要特征
信息沿着输入路径进入系统,由外部形式变换为内部形式后,到达某个数据加工(称为**事务中心**),然后该事务中心根据输入信息的类型,在之后的多条“加工路径”中选择一个去执行
事务中心的任务:接收事务信息;**根据事务类型选取一条加工路径执行**
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-15-04-35cf7ae442a336836669733fe38f0b73-upload_918eb68d5fb5a495026a5fdd1efebfd2-e750f4.png =500x)
* 事务分析
1. 在事务型DFD上区分出输入部分、事务中心和发送部分(由事务中心发射出的多条加工路径构成),并划出分界线
2. 顶层结构只包含一个主模块。**第一层结构主要包括两个分支:输入分支和发送分支**
3. 输入分支:简单映射,与变换分析过程近同
4. 发送分支:**包含一个调度模块,对应事务中心**。由事务中心发射出的每条加工路径可根据其各自的流特征(变换型或事务型)映射成相应结构,由调度模块**选择调用**
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-15-13-59c6e3d07e717cb6ac0476ac35061dfd-upload_e1a013919c0948a2a0813d82445d0491-de2388.png =550x)
* 结构图SC的优化
* 尽可能减少高扇出结构
模块扇出数以**3\~4为宜**,**最多不超过5\~7**
调整方法:对其下属模块进行归类,并适当增加中间层的控制模块,以减少扇出
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-15-21-bb3e6af9b9eafaf3a97c05e54401e691-upload_8ed7c4857ca0dd5e39bce4abe05a4e20-620d75.png =500x)
* 应随着深度逐渐增大扇入
尽量提高**底层结构的重用率**
一个良好的结构,通常**上层扇出较高,中层扇出较低,底层*扇入*较高**
例:
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-15-33-671aa0441083405f51f45640e2c27a6c-upload_5b3bd904848ca052a04225399a547e38-f5e830.png =300x)
合理划分次级模块可以得到:
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-15-40-824c05037dec4c36caee99083bcf7673-upload_cae06570237c03f1c24fdd183864f07e-98abf4.png =300x)
* SD方法中常用的过程设计描述工具
* 图表工具
* 程序流程图(程序框图)
* N-S图(盒图)
* PAD图(问题分析图)
* 判定树(决策表)/判定表(决策树)
* 语言工具
* PDL(过程设计语言)
## 4.4 用户界面设计
用户界面(User Interface, UI):使用者与软件/硬件设备之间搭建的一种沟通交流的手段和媒介,使信息能够在二者之间相互传递的接口
软件用户界面的典型类型
* CLI
* GUI
软件用户界面的组成部分
* 信息输入
* 键鼠输入
* 硬件接口输入
* 软件接口输入
* 指令输入
* 键盘输入
* 直接操纵图形元素
* 信息输出
* 单一/成组/大量
* 软件接口输出
* 动态数据输出
软件用户界面的设计基本原则
* 置系统于用户的控制之下
* 减少用户的记忆负担
* 保持界面的一致性
* 个性化
* 宽容性
* 反馈
* 美观性
* 可用性
* 简洁性
# 5 软件测试
## 5.1 软件测试基础
软件测试的概念
* 软件测试:根据程序的*内部逻辑结构(源代码/程序流程图)* 和 *功能规格说明* 来设计测试用例,并利用这些测试用例运行程序,以发现程序中存在的错误和缺陷
测试用例
* 输入数据:被测程序在运行时所接受的输入数据
* 预期输出结果:对于相应的输入,程序在没有错误的情况下,应该产生的正确输出结果
测试用例的设计原则:
* 代表性
* 既要能代表各种**合理**的输入数据,也要能代表各种**不合理**的输入数据
* 可判定性
* 每个测试用例都应该有期望的输出结果,用于判定程序运行的正确性
* 不唯一性
软件测试中的"错误群集"现象
* 在测试中,对于已发现错误数量较多的模块,其残留的错误数量可能也较多
常见的测试方法分类
1. 从是否需要执行被测程序的角度划分
* 静态测试
* 动态测试
2. 对于动态测试又可分为两大类典型测试
* 黑盒测试(不必穷举输入)
* 不考虑内部逻辑结构,直接使用测试用例
* 白盒测试(不必穷举路径)
* 介入内部逻辑结构,遍历所有可能的内部逻辑路径
软件测试信息流
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-16-09-c978a2babccec2f4366be924c6a6030c-upload_bfc4ab553de19fcfe6754f997375dcd5-e7cf58.png =500x)
测试环节的输入:
* 软件配置:软件开发前期各个阶段得到的软件文档
* 测试配置:主要包括测试阶段的测试计划,方案,用例,环境
## 5.2 软件测试过程
软件测试过程遵循**自底向上,逐步集成**的方式
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-16-18-6fa6b4c0a3c5ee9fb795e1e8a4cbbc2a-upload_bd9a23bab684ec9b370910dc7fcdad51-7ad93d.png =400x)
软件测试过程按照先后次序分为以下几个步骤:
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-16-27-9e2c63b61889b7c8d914196d7ea8c881-upload_b70a4887fd902d4617fc188193d72adc-371fcc.png =400x)
1. 单元测试
* 测试对象
对每个程序模块进行正确性检验
* 测试依据
以详细设计说明和源代码为依据
* 测试方法
主要采取**白盒测试**
* 主要内容
1. 模块接口测试(I/O测试)
2. 局部数据结构测试(类型声明,初始化,缺省值等的正确合理性)
3. 独立路径测试
4. 出错处理测试(是否设置出错处理通路)
5. 边界条件测试
* 单元测试环境
* 为了避免上下模块的潜在bug和错误,同时简化测试流程,都不实际采用而是使用**驱动模块**(模拟上层)和**桩模块**(模拟下层)来模拟与被测模块相关联的其他模块,从而构成被测模块的单元测试环境
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-16-37-2cb0ea2b010ca90d0bf52b59169e7e37-upload_f5f0949501eb19ed842f5d19abcf2b56-e21ccd.png =400x)
2. 集成测试(组装测试)
* 测试对象
按照软件体系结构的要求,将各个模块通过接口连接在一起,**检查所构成的子系统是否正确运行**
* 测试依据
概要设计说明与详细设计说明
* 集成测试方式
一次性集成/渐增式集成(渐增式集成与模块测试同时进行)
* 自顶向下渐增性集成
* 自底向上渐增性集成
* 三明治式渐增性集成
* 基准层及其以上各层采用自顶向下方式;基准层及其以下各层采用自底向上方式
3. 确认测试
* 有效性测试:
* 检查集成后的软件系统在功能和性能上是否满足需求规格说明中所确认的标准,即检查软件系统与用户需求是否一致
* 测试依据
以需求规格说明为依据
* 测试方法
主要采用**黑盒测试**方法
* 软件配置审查
* 检查各种软件文档(包括需求文档、设计文档、源程序代码清单、测试文档等)是否完整正确
* 目的是保证与软件开发有关的所有文档都完整、齐全,便于后期维护阶段使用
## 5.3 黑盒测试用例设计
1. 等价类划分法
* 基本思想:
将被测程序的输入域划分成若干个等价类,在每个等价类中选取一些代表性数据作为测试用例,即用少量的代表性输入数据来代替整个输入域
* 等价类的两种类型
* 有效等价类
对于被测程序来说,是合理的、有意义的,符合功能规格说明要求的输入数据构成的集合
* 无效等价类
反之如上
* 基本原则
* 若功能规格说明中,对于输入数据规定了取值范围,则由此可以确定一个有效等价类和两个无效等价类
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-16-49-42154fe60aa2b184cdfe5909c4bc531a-upload_dacf8728583a982d6dca3a37a4b898f3-bf3df5.png =400x)
* 若功能规格说明中,对于输入数据规定了“必须如何” 或 “不能如何”的情况,则由此可以确定一个有效等价类和一个无效等价类
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-16-57-8b10ef023be0e14200b7e811765a04b6-upload_3a1c80d12a5eddab34bf0c3ccf3d56d0-209940.png =400x)
* 若功能规格说明中,规定了输入数据的一组可能的取值(比如$n$个),并且程序要用不同的方式对每一个输入值分别处理,则由此可以确定n个有效等价类和一个无效等价类
* 基本过程
1. 建立一个等价类表,列出所有的有效等价类和所有的无效等价类,并为每个等价类分配一个编号
2. 从每个等价类中选择测试用例进行覆盖
* **每次尽可能多的覆盖有效等价类**
* **每次只覆盖一个尚未覆盖的无效等价类**
* 典例
某城市的电话号码由3部分组成,这3部分的名称和内容规定如下:
* 地区码:空白或3位数字
* 前缀:3位数字,开头不能是0和1
* 后缀:4位数字
假设被测程序能接受一切符合上述规定的电话号码,拒绝所有不符合规定的号码,试用等价类划分法设计它的测试用例
解:
1. **确定等价类,建立等价类表**
![](https://pic-static.yilantingfeng.site/imgs/2022/05/25/15-24-06-79ce1bc148968b8a24d1f9ce3f05841f-20220525152406-b8e0f3.png =500x)
2. 设计测试用例,覆盖所有的等价类
2. 边界值分析法
**边界值分析法是等价类划分法的补充。通常,两种方法相结合使用**
* 基本思想
根据等价类的边界条件来设计测试用例。即在**等价类的边界处**选取数据作为测试用例,而不是在等价类内部选取典型值
* 基本原则
* 如果输入条件规定了取值范围,则可以选取正好等于该范围边界的值(有效等价类);刚刚超过该范围边界的值(无效等价类)作为测试输入数据
* 如果输入条件规定了输入值的个数,则用最大个数、最小个数(有效等价类);比最小个数少1,比最大个数多1(无效等价类)的数据作为测试输入数据
* 简单来说,等价类划分法是一种测试思想,而边界值分析法则是一种对测试用例的选择方法,二者需联用
3. 因果图法
* 基本思想
* 被测程序的输入条件称为"因",输出结果称为"果"
* 因果图:用来表达输入条件的各种取值组合情况与输出结果之间的对应关系
* 该方法主要检查被测程序在**输入条件的各种取值组合**情况下,是否能够产生正确的输出结果
* 基本过程
1. 分析被测程序的功能规格说明,找出所有的输入条件(简称原因)和所有的输出结果(简称结果),并分别用原因结点和结果结点来表示
2. 分析被测程序的功能规格说明,找出原因与结果之间的对应关系,根据这些关系,画出因果图
![](https://pic-static.yilantingfeng.site/imgs/2022/05/25/15-32-26-d26bbe6d2be12f911b275fff56461ce9-20220525153225-886f9d.png =500x)
3. 在因果图中标明某些原因与原因之间可能出现的约束关系(由于这些约束的存在,导致原因与原因之间的某些组合情况不可能发生)
![](https://pic-static.yilantingfeng.site/imgs/2022/05/25/15-33-05-36217221f801388a301cafc03626bdd7-20220525153305-c1ba15.png =550x)
4. 将因果图转换成判定表
5. **根据判定表中的每一列,设计测试用例。一个测试用例覆盖一列**
![](https://pic-static.yilantingfeng.site/imgs/2022/05/25/15-35-56-64fbaaa1acc453f9ea91f5e919e51603-20220525153555-0858c9.png =200x)
* 典例
某程序功能为根据输入的文件名修改相应的文件。**文件名第一个字符必须是字母A或B**,**第二个字符必须是数字**。若输入的文件名满足规范,**则执行文件修改操作**;若输入的文件名第一个字符不正确,**则给出提示信息N**;若输入的文件名第二个字符不正确,**则给出提示信息M**。试用因果图法设计测试用例
解:
1. 找出输入条件和输出结果
![](https://pic-static.yilantingfeng.site/imgs/2022/05/25/15-37-39-e70223003cab5d5907b791e2c778bea4-20220525153739-3fff30.png =500x)
2. 画出因果图并标出约束关系
![](https://pic-static.yilantingfeng.site/imgs/2022/05/25/15-38-37-5143370af82e50abe9e72743a0b4e469-20220525153836-1cc7ec.png =500x)
3. 根据3个输入的条件,得出8列的的**判定表**,并排除其中的不可能情况
![](https://pic-static.yilantingfeng.site/imgs/2022/05/25/16-32-10-02ac1df26547a76ef499dad25f8c3cb2-20220525163209-3003e5.png =500x)
4. 对每一列设计一个测试用例
![](https://pic-static.yilantingfeng.site/imgs/2022/05/25/16-32-43-4e754d5b4c72b4011ee238b62716dbe7-20220525163243-617588.png =500x)
## 5.4 白盒测试用例设计
白盒测试用例中的输入数据从程序内部的逻辑结构导出,预期输出是从程序的功能规格说明中导出
白盒测试考虑测试用例对**程序内部执行路径的覆盖程度**
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-17-05-e808755eb33db681365770e010ca5f27-upload_7097d488dbb60e3bf1172d7844defdb2-17a86b.png =400x)
1. 逻辑覆盖法
五种覆盖标准(从弱到强)
* 语句覆盖
设计测试用例,使被测程序中的**每条语句都至少执行一次**
* 判定覆盖
设计测试用例,使被测程序中每个判定的**每个分支(真分支和假分支)都至少执行一次**
* 条件覆盖
设计测试用例,使被测程序中**每个判定中的每个条件,分别按“真”和“假”都至少执行一次**
* 判定-条件覆盖
设计测试用例,使被测程序**同时满足判定覆盖和条件覆盖的要求**
* 条件组合覆盖
设计测试用例,使被测程序中每个判定中**所有的条件取值组合都至少执行一次**
2. 基本路径测试法
以**程序控制流图**为基础,计算被测程序的**环路复杂度**$V$,进而定义出被测程序的一个**基本路径集合**(由一系列的独立路径组成),最终导出测试用例,使得每个测试用例覆盖一条独立路径
* 程序控制流图
* 一种**简化**的程序流程图
* 只表现程序的控制流走向
* 不表现对数据的**具体处理操作**以及分支或循环的**具体判定条件**
* 节点的映射
* 程序中的一条语句可以映射为一个结点
* 程序中的一个判定条件可以映射为一个结点
* 程序中一组顺序执行的多条语句也可映射为一个结点
* 在分支结构中,真分支与假分支的汇合处即使没有语句也可以映射为一个结点
* 若程序中的某个判定表达式是由一个或多逻辑运算符连接而成的**复合条件**,则不可以将判定直接映射为一个结点,而是**将该判定修改为一系列只有单个条件的判定的嵌套**
例:``if(a||b) x; else y;``映射为
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-17-14-2e1addddb367d053877c45a7de5c7d3d-upload_035f12df767797357daff7be40388110-e05b15.png =200x)
* 环路复杂度
* 环路复杂度$V$越大,则程序内部逻辑结构的复杂度越高
* 在基本路径测试法中,环路复杂度$V$决定了基本路径集合中独立路径数目的上限值
* 计算法
1. $V$=边数-节点数+2
2. $V$=区域个数
3. **$V$=判定节点个数+1**
* 独立路径与基本路径集合
* 在程序控制流图中,一条独立路径至少应包含一条在定义该路径之前不曾走过的新边
* 基本路径集合中的独立路径数目最多$V$条
* 基本路径集合不唯一,但一定要确保控制流图中的每条边都至少经历一次
小结:
* 根据程序流程图或源程序代码,导出相应的控制流图
* 计算控制流图的环路复杂度$V$
* 确定由最多$V$条独立路径构成的一个基本路径集合
* 为基本路径集合中的每条独立路径设计测试用例进行覆盖
例:
```=
INPUT (A, B, C, D)
IF (A>0) AND (B>0)
THEN X=A+B
ELSE X=A-B
END
IF (C>A) OR (D<B)
THEN Y=C-D
ELSE Y=C+D
END
PRINT(X, Y)
```
得到控制流图
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-17-23-ecb19f3ad348f9eaf3230366abc6ba26-upload_1f8e658e7efbc973731ea2ace35513b5-2baccd.png =150x)
判定节点为2,3,7,8
环路复杂度$V$=4(判定节点个数)+1=5
可以确定一个独立路径集合如下
Path1:1-2-3-4-6-7-9-11-12
Path2:1-2-5-6-7-9-11-12
Path3:1-2-3-5-6-7-9-11-12
Path4:1-2-3-4-6-7-8-9-11-12
Path5:1-2-3-4-6-7-8-10-11-12
再依据此设计测试用例即可
# 6 面向对象的分析
> 统一建模语言UML:一种图形化的建模技术,用不同的图来构建系统的各种模型
> UML主要用于面向对象软件开发方法,不适用于结构化方法
> 本章中包括的UML图:用例图、类图、活动图(或泳道图)、时序图(或协作图)
## 6.1 面向对象方法概述
面向对象软件开发过程模型——喷泉模型
* 面向对象开发过程中,各阶段之间形成频繁的迭代;
* 各阶段均采用统一的“对象”概念,使得各阶段之间形成“无缝”连接。
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-17-30-6daa84d51c887f70d8ff63adcac4851e-upload_21ad730645bb6c924535437066ac8e99-62cb56.png =300x)
面向对象方法的基本概念
* 面向对象=对象+类+继承+消息通信
* 对象
* 用来描述现实世界中客观存在的事物
* 对象是构成软件系统的一个基本单位。它由一组属性以及作用于这组属性的一组操作(也称方法)共同构成
* 属性:描述对象静态特征的一个数据项
* 操作(或方法):描述对象动态特征的一个函数或过程
* 类
* 具有相同属性和相同操作的一组对象可归并为一个“类”
* 类是抽象的,对象是具体的
* ``public:+ private:- protected:# ``
* 封装
* 把对象的属性和操作封装在一起形成一个独立的整体,从而对外界隐藏了对象内部的所有实现细节
* 封装特性将对象的外部接口(可见)与内部实现细节(不可见)分离开
* 继承
* 一个类可以派生出子类,子类可以自动拥有父类的全部特性(包括属性和操作),同时也可加入自己的新特性,这种机制称为继承
* 多态性
* 在父类中定义的属性或操作被子类继承后,可以具有不同的数据类型或表现出不同的实现方式
* 消息
* 消息是一个对象向其它对象所发出的服务请求
* 一个对象向另一个对象发出消息,请求某项服务,另一个对象接收该消息后,触发自己的某个操作(方法)响应该消息请求,并将执行结果返回给发出消息的对象。从而,形成对象之间的消息通信
* 类间关系
1. 泛化关系
* 也称继承关系,表示一般(基类)与特殊(继承类)的关系
* UML图中泛化关系的表示符号
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-17-40-45d1969b47592baafa5e25e6c27f4c6a-upload_6aa38cea876bd629c5ef51b67ca44f27-2b21b9.png =300x)
2. 组成关系
* 表示一个类是另一个类的组成部分,即类之间的“整体与部分”的关系
* 具体分为
* 聚合关系
* 整体类对象与部分类对象在**生命周期上是相互独立**的
* UML图中聚合关系的表示符号
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-17-48-b01a729193b43c3d47ae2a6c91ccb413-upload_4d3ce46d4517504afb57636d44900673-7ded2e.png =300x)
* 组合关系
* 整体类对象与部分类对象**具有相同的生命周期**的
* UML图中组合关系的表示符号
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-17-58-f66bb8993c5ce44b0c3adced51e184f0-upload_1fe2c3a6c6c7519fa342978a402fee40-a9d04d.png =310x)
* 关联关系
* 表示对象之间**长期存在的一种静态联系**
* 关联关系也可以理解为两个类之间存在着某种语义联系
* 单向关联
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-18-08-0cd6d44c94d9b3ca028317e349c39aeb-upload_a8e2d3e2d09be2539d1e2637b57c32dd-8829ec.png =400x)
* 双向关联
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-18-19-5b848d705e0fe21f546459d20f1732fe-upload_ca2e88cef6a90310d24f43a82c6f5116-83dc6e.png =400x)
* 多重性
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-18-29-4fdd18480d74b9ab3a4fe10bf1dc1fd6-upload_98d89bad5e8b5dc24f9a4a92c68378a0-9feb40.png =500x)
* 依赖关系
* 表示对象之间**临时存在**的一种**动态**联系, 这种联系一般是通过对象之间的**消息通信**加以展现,因此也称为“消息连接”
* 以下情况通常会引起类之间的依赖关系
* 一个类是另一个类的某个操作(或方法)的参数
* 一个类在另一个类的某个操作(或方法)中被使用
* UML图中依赖关系的表示符号
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-18-37-eb756294ba40d57de5604241a2a03ba3-upload_658ef96648746d7cc8fe20ca9f6bd511-ba940f.png =400x)
* 小结
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-18-45-c86933a0a31dc8e421c7b46a9a74ea63-upload_174b611c8ae0465ec6fb6a46361f6d32-a03736.png)
面向对象分析(Object Oriented Analysis,OOA)
* 主要使用UML中的以下几种图来描述OOA模型:
* 用例图
* 类图
* 活动图(或泳道图)
* 时序图(或协作图)
* 三个独立模型
* 用例模型
从用户的角度获取功能需求
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-18-58-b5795af0a0bf5ec48185e733474df18b-upload_1d4e6a7dd3d421c073a73ceb64466cc3-0fe658.png =150x)
* 静态结构模型
描述系统的概念实体
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-19-05-22de2c60019d979358799deef38b452f-upload_6e84e410fd0dcb47eef955435550d531-fca47e.png =180x)
* 动态行为模型
描述对象之间的交互行为
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-19-12-6afbd94a3acded728bc868fbd1fae511-upload_669047b7f24b346ba4410ff06305cc58-521965.png =400x)
## 6.2 用例模型
用例方法是一种新的需求分析技术
* 用例建模的基本思想
用户并不关心系统的内部结构和设计,而只关心使用层面。因此用例模型就是**从用户的角度获取系统的功能需求**
* 用例模型的组成
1. 角色
也称参与者,位于目标系统外部,并与目标系统发生交互的人员或其它软件系统或硬件设备,代表目标系统的使用者或使用环境
在UML中的符号表示:
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-19-22-98aadb652c5753af6e246818ee911063-upload_7e0fc5b216f0cc54ef2c4bad23922011-d42001.png =110x)
2. 用例
用例模型中的核心元素,**一个用例代表目标系统向外所提供的一个完整服务或功能**
用例定义了目标系统是如何被角色所使用的
在UML中的符号表示:
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-19-32-3b267c6697f56ba8692a731afee286a8-upload_701121a3a3c5974b489dee6bb80467e9-75976f.png =110x)
用例的基本特征:
* 用例由角色启动(即角色驱动):由某个人、某台设备或某个外部系统等角色,来触发系统的某个用例开始执行(被动性)
* 执行中的用例可看作是一组行为序列:描述了角色与系统之间发生的一系列交互(接收用户输入、系统执行某些动作、产生输出结果等)
* 一个用例执行结束后,应为角色产生可观测到的、有价值的执行结果(输出性)
3. 通讯关联
表示角色与用例之间的对应关系:某个角色使用了系统中的哪些服务(用例);系统所提供的某个服务(用例)又被哪些角色所使用
在UML中的符号表示
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-19-45-cab7e5f2d20e4669ecc54bca06b8b2ca-upload_f9519db675ed703f31cfc95218882760-873647.png =330x)
* 用例建模的基本过程
1. 识别角色
* 谁**使用**系统的**功能**?
* 谁从系统**获取信息**?
* 谁向系统**提供信息**?
* 谁来负责**维护和管理**系统以保证其正常行?
* 系统需要访问哪些**外部硬件设备**?
* 系统需要与哪些**其它软件系统**进行**交互**?
其中包括一个特殊的角色,**系统时钟**,用来解决一些定时执行的操作。**这一角色应该被理解成是系统外部的**,由它来触发系统所提供的用例对话
以图书管理系统为例
有角色:普通读者,图书管理员
2. 识别用例
根据不同的角色,考虑角色需要系统为其提供什么样的功能
* 角色**使用系统完成什么任务**?
* 角色是否会在系统中创建、修改、删除、访问、存储**数据**?若是,角色又是如何完成这些操作的?
* 角色是否会将外部的某些事件通知给系统?
* 系统是否会将内部的某些事件通知给角色?
**每个用例至少应该涉及到一个角色,且每个角色也至少涉及到一个用例**
以图书管理系统为例
普通读者有用例:登录;预订图书;取消预订;查询浏览图书信息
图书管理有用例:登录;管理读者信息;管理图书信息;登记借书;登记还书
3. 识别角色与用例之间的通讯关联,并绘制用例图
以图书管理系统为例
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-19-52-236b10dfffcf0728dfd78a86f8e354cf-upload_71df31dfb24dbf81f5b84968e7c9d345-b1bfcc.png =450x)
4. 给出每个用例内部的详细描述(用例说明)
用例说明包括:
* 描述:简要介绍该用例将完成什么功能或操作
* 角色:该用例由哪个角色来启动/触发
* **事件流**
* 用例是如何启动的,即**哪些角色在何种情况**下启动该用例开始执行
* 用例执行时,**角色与系统**之间的**交互过程**
* 用例执行时,在不同情况下可以选择执行的多种方案(常规流与备选流)
* 在什么情况下用例被视作执行结束
* 前置条件:该用例在满足什么前提条件下才能执行
* 后置条件:该用例执行完后会达到什么结果
事件流具体分为两类:常规事件流与备选事件流
* 常规流
* 描述用例执行过程中**最正常,最一般**的一种场景,系统执行一系列活动步骤来响应角色提出的服务请求
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-20-00-df1ad91a540ee54085a46dd9f2c6f716-upload_0da2193bc87532289fe1d5e151bc9870-b767f0.png =180x)
* 备选流
* 描述用例执行过程中,当出现某些异常或偶然发生的情况时,系统可能选择执行的另外一组活动步骤
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-20-07-a66292d3599e19e3a6b17bbcda284a60-upload_9bbbbcbaedd639662f84b9eb050fefd5-9a3240.png =180x)
以图书管理系统为例
登记借书用例当中
```
用例:登记借书
1.目标:本用例允许图书管理员登记普通读者的借书记录。
2.角色(参与者):图书管理员
3.事件流:
3.1 常规流程:
当读者希望借书、图书管理员准备登记有关的借书记录时,本用例开始执行。
(1) 系统要求图书管理员输入读者的注册号和所借图书号;
(2) 图书管理员输入信息后,系统产生一个唯一的借书记录号;
(3) 系统显示新生成的借书记录;
(4) 图书管理员确认后,系统增加一个新的借书记录,用例结束。
3.2 备选流程:
(1) 读者没有注册
主流程中,若系统没有该读者的注册信息,系统将显示错误提示,用例结束。
(2) 所借图书不存在
主流程中,若所借图书已被借出或者系统中无该图书,系统将显示错误提示,用例结束。
4. 前置条件:用例开始前,图书管理员必须在系统登录成功。
5. 后置条件:如果用例执行成功,该读者的借书记录被更新,否则,系统状态不变。
```
5. 细化用例模型
将已有的角色/用例通讯关联细化为
* 角色与角色之间的泛化关系(generalization)![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-20-19-3f27bc8e9510efac344185640c6a26e1-upload_8fba4b0e813f5ad6fffc6e8a99426db7-893713.png)
* 多个角色子类可以泛化为角色父类
* 用例与用例之间的泛化关系(generalization)![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-20-35-3f27bc8e9510efac344185640c6a26e1-upload_8fba4b0e813f5ad6fffc6e8a99426db7-2259bb.png)
* 多个用例子类可以泛化为用例父类
* 用例与用例之间的包含关系(include)![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-20-41-5a556751553eac2579493909c444e6ad-upload_7949b25f70adeadabc4a24e6741ac0ef-51ccbf.png)
* 执行一个用例**必然**会使用到另一个用例
* 用例与用例之间的扩展关系(extend)![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-20-51-0f9a8d2e13550245dbf655179a3fc5f1-upload_19352ceeaf02e3cd4efe69844a7d645b-22210f.png)
* 执行一个用例**只在某些特定情况下**会使用到另一个用例
* UML中的活动图与泳道图
对用例说明的图形化补充。提供一种可视化的流程图方式,对用例的事件流进行直观展示
基本元素:
* 起始点、结束点、泳道
* 活动、活动之间的时序连接
* 决策点、活动之间的并发点
活动图:
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-20-58-f0f86b397ae7ab82c4dd9b1f3a18d039-upload_16cb8c0afeffc873e52b67947964d535-5adcac.png =400x)
泳道图:
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-21-06-478f7088b971ff5b974c223868143664-upload_176bb10c5226b866396f801aeac0eabb-c52323.png =400x)
* 典例
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/16-53-06-0c77b0024e905919d27d26b1031e0be0-se_chp6_2_example_页面_1-c9c595.jpg)
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/16-53-06-dabd7daae1204d72a0cf1c2129971487-se_chp6_2_example_页面_2-e123cf.jpg)
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/16-53-06-86c5aeacd701f5a357cbb1183c02b6af-se_chp6_2_example_页面_3-39c2f5.jpg)
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/16-53-06-b4eacca2da5b339927fb9c3374fd0738-se_chp6_2_example_页面_4-b26f85.jpg)
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/16-53-06-01d71a503bd9ef8b25f46140bb82815e-se_chp6_2_example_页面_5-92cde5.jpg)
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/16-53-06-3f35c5bde8dd3ad231de8829def10378-se_chp6_2_example_页面_6-d6126f.jpg)
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/16-53-06-28e201ad10d4e7533eef56babd089ac4-se_chp6_2_example_页面_7-e49ad2.jpg)
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/16-53-06-79c5b9b77554b096e7842179fc959726-se_chp6_2_example_页面_8-f236d5.jpg)
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/16-53-06-53e18a738eb4abc9048cfbf2d470a2e4-se_chp6_2_example_页面_9-897af0.jpg)
## 6.3 静态结构模型与动态行为模型
面向对象分析的基本过程
1. 建立用例模型
2. 从用例模型入手,识别"分析类"
3. 识别类之间的关系,绘制类图(静态结构模型)
4. 定义分析类对象之间的交互行为,绘制时序图或协作图(动态行为模型)
5. 识别分析类的属性和操作
6. 评审OOA模型
分析类是概念层次上的内容。在面向对象分析阶段(OOA阶段)所描述的类,**统称为分析类**。分析类直接与系统的应用逻辑和需求相关,而与技术实现无关
* 边界类
* 用于描述系统外部的角色与系统之间的交互接口
* 目的:将用例内部的执行逻辑与外部环境进行隔离,使得外界环境的变化不会影响到内部的逻辑部分
* 三种类型:用户界面(着重描述交互信息而不是交互形式)、软件系统接口、硬件设备接口
* UML中边界类的表示:
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-47-42-82a612ac5f9819568847a18c1a113f03-20220511174741-d04016.png =500x)
* 实体类
* 对应现实世界中的"事物"
* UML中控制类的表示:
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-48-34-bec109e918ed3caec50501879dc14c97-20220511174833-1145b9.png =520x)
* 控制类
* 描述用例所具有的事件流的执行逻辑。控制类本身不处理具体的任务,而是调度其它类来完成具体任务
* 任务:控制类负责**协调边界类和实体类**:控制类**接收**由边界类收集上来的信息或指令,然后根据用例的执行逻辑,再将具体任务**分发**给不同的实体类去完成
* **控制类实现了对用例行为的封装,将用例的执行逻辑与边界和实体进行隔离**
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-51-02-97e9a439174ee4e25357530feae0316d-20220511175102-f6ef8b.png =500x)
* UML中控制类的表示:
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-50-12-b148c52f7d526d13d0686ed00f02038f-20220511175012-84587a.png =500x)
**典型的OO分层:**
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/20-00-02-8b7aa63972678e15bcd457a08e440fa8-20220511200001-4e40ab.png =550x)
识别分析类
1. 识别边界类
通常,用例模型中的一个角色与一个用例之间的通信关联对应一个边界类
2. 识别控制类
控制类负责协调边界类和实体类。通常在现实世界中没有对应的事物
控制类与用例存在密切关系:通常,用例模型中的一个用例对应一个控制类
3. 识别实体类
实体类通常是用例中的一些参与对象,对应着现实世界中的“事物”
识别实体类之间的关系,绘制类图(也称领域类图)
* 泛化(generalization)
* 组合(composition)
* 聚合(aggregation)
* 关联(association)
* 依赖(dependency)
典例
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-53-52-de48cb7e24ccff9d7aec9d83e2f072f3-se_chp6_3_example_页面_1-5621d4.png)
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-53-52-deae68be425e6779f74e4bbdbe1d4f2e-se_chp6_3_example_页面_2-b175bd.png)
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-53-52-1bc8b80812a430e258b06da3f67df1e9-se_chp6_3_example_页面_3-268537.png)
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-53-52-7b2c75ba5f45f4b2b041ba41adc9b8a9-se_chp6_3_example_页面_4-8289d6.png)
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-53-52-c63b551f60fd2e4f9f829f5c6a86d42b-se_chp6_3_example_页面_5-08ea0d.png)
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-53-52-ad5cad5499c5792b888de7e08daba4ed-se_chp6_3_example_页面_6-ee7f4f.png)
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-53-52-92454019f81d496e96adbe6ce24674b8-se_chp6_3_example_页面_7-327092.png)
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-53-52-9952aa8e8f28cbc5ccde4b9c4ea063ed-se_chp6_3_example_页面_8-2c35ca.png)
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-53-52-a1c987fffadcc1f19ce705e8ce1c9ad1-se_chp6_3_example_页面_9-0d6c86.png)
# 7 软件维护
## 7.1 软件维护的概念
软件维护:软件在**交付给用户使用之后**,为了修改软件错误或满足需求变化而变更软件的过程
**主要分为三种维护类型**
1. 改正性维护
由于软件测试不彻底,软件交付使用后,在运行阶段会暴露出一些开发时未能测试出来的错误。对这些错误进行修改的过程称为改正性维护(修bug)
2. 适应性维护
软件系统所需的外部环境或数据环境,在软件运行阶段可能会更新升级。为了使软件系统能够适应这种运行环境的变化,而对其进行相应的修改,这种维护称为适应性维护(兼容性升级)
3. 完善性维护
在软件使用过程中,用户可能会对软件提出新的功能或性能要求。为了满足这些要求,需要修改软件,以扩充软件功能、增强软件性能,这种维护称为完善性维护(加功能)
在软件交付使用**初期,改正性维护的工作量较大**。随着错误发现率不断降低,软件开始进入正常使用期。在之后长期的使用过程中,**由于运行环境不断更新,用户需求不断变化,适应性和完善性维护的工作量逐步增加**
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-21-17-11ab51c07dc234d8c1cb9f4c10883a21-upload_1027232238b5dcd206d1b1d29eda1eee-7e3c00.png =350x)
## 7.2 软件维护的特点
* 软件维护受开发过程影响大
* 软件维护困难多
* 软件维护成本高
## 7.3 软件的可维护性
软件的可维护性:是指维护人员进行软件维护活动时的难易程度。通常与软件的以下七种特性有关
* 可理解性
指软件被理解的难易程度(根据代码和文档)
提高软件可理解性的方法:模块化原则、良好的程序设计风格等。
* 可测试性
指诊断和测试程序的难易程度
* 可修改性
指修改程序的难易程度
* **可靠性**
指软件在达到用户要求和设计目标的基础上,在给定的时间间隔内能够正确、无故障运行的概率
常见的两个量化指标
* **平均无故障时间(Mean Time Between Failure,MTBF)**
指软件正确运行的平均时间,主要取决于软件中潜在错误的数量
$E_T$,测试之前程序中的错误总数
$I_T$,程序长度
$t$,测试时间(自变量)
$E_d(t)$,在0至$t$期间发现的错误数量
$E_c(t)$,在0至$t$期间改正的错误数量
设程序的失效率与程序中剩余错误数量成正比,而MTBF与剩余错误数量成反比。
设发现的每个错误都能立即正确改正,即:$E_c(t) = E_d(t)$
则剩余错误数量为:$E_r(t) = E_T-E_c(t)$
则单位长度的剩余错误数量:$\varepsilon_r(t) = [ E_T-E_c(t) ] / I_T$
**估算MTBF与单位长度的剩余错误数量成反比**
$\begin{align} \text { MTBF }=\frac{1}{K \cdot \varepsilon_{r}(t)}=\frac{I_{T}}{K \cdot\left[E_{T}-E_{c}(t)\right]} \end{align}$
估算错误总数$E_T$的两种方法:
* 错误植入法
设人为植入错误的总数为$N_S$,经过一段时间的测试之后,发现$n_s$个植入错误以及$n$个原有错误
$\begin{align} E_T \approx \frac{n}{n_s}N_s \end{align}$
* 分别测试法
由两个测试人员甲和乙,分别测试同一个程序,用$t$表示测试时间,并假设:
$t = 0$时:错误总数为$B_0$
$t = t_1$时:测试员甲发现的错误数量为$B_1$
$t = t_1$时:测试员乙发现的错误数量为$B_2$
$t = t_1$时:甲和乙发现的相同错误的数量为$b$
$\begin{align} B_0 \approx \frac{B_2}{b}B_1 \end{align}$
每隔一段时间对甲和乙的测试结果按上述方法进行分析,并用上式计算出若干个$B_0$,最后可用$B_0$的平均值作为$E_T$的估计值
* 平均修复时间(Mean Time To Repair,MTTR)
* 可移植性
指把软件从原有的计算机环境转移到另一个新的计算机环境的适应能力
* 可重用性
指软件中的某一功能模块不需要修改或稍加改动之后即可在不同的软件系统中多次重复使用
例如:基于复用的过程模型
* 效率
## 7.4 软件维护的基本过程
* 建立维护组织
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-21-25-072ed9dbfb511ca0ac4b36955ef2e7e4-upload_55f364100a487e3791cdd4f1d5b126f4-0a1ece.png =400x)
* 软件维护文档
* 维护申请报告
* 软件修改报告
* 软件维护流程
![](https://pic-static.yilantingfeng.site/imgs/2022/05/11/17-21-31-d3bc407f5ce2fd7cdad7be1b0fd439b6-upload_960f47b2eda8656ff8181ac2ca8a91cc-7f9461.png =400x)
# 软件工程简答记忆
* **什么是软件,有哪些特点。**
* 软件是计算机系统中与硬件相互依存的部分。他是包括计算机程序、数据以及软件文档的完整集合
* 特点:
* 软件是一种抽象的逻辑实体,不是具体的物理实体(抽象性)
* 软件产品没有明显的制造过程,其生产过程主要是开发
* 软件产品的维护比硬件复杂(存在退化问题,需要维护与更新)
* 软件的开发和运行对计算机系统存在依赖性(可移植性)
* 软件本身的复杂性(问题域的复杂性)
* **软件危机的主要表现有哪些?**
* 对软件开发成本和开发进度估算不准确,严重拖期或超出预算
* 无法满足用户需求,导致用户很不满意
* 软件可维护性差,难以更改、调试和增强
* 软件质量不可靠,经常失效
* 软件缺少必要适当的软件文档,使用不便
* **什么是软件工程,包括哪些基本要素,简要说明这些要素的作用。**
* 软件工程是将系统性的、规范化的、可度量的方法应用于软件开发、运行和维护
* 基本要素:
* 方法:提供如何开发软件的相关技术(结构化方法/面向对象方法)
* 工具:为软件开发提供各种辅助性的工具软件,以提高开发效率和软件质量
* 过程:规定了一系列软件工程活动,以及活动的执行步骤和细节
* **什么是软件生存周期,通常划分为哪些阶段?**
* 从软件产品最初定义开始,到交付用户使用,直至最终废弃淘汰的全过程
* 阶段:制定计划$\rightarrow$需求分析$\rightarrow$软件设计$\rightarrow$程序编码$\rightarrow$软件测试$\rightarrow$运行维护
* **比较瀑布模型、增量模型、原型模型和螺旋模型各自的特点。**
* [参见——软件工程模型
](https://md.yilantingfeng.site/s/WCvKm22cV#15-%E8%BD%AF%E4%BB%B6%E7%94%9F%E5%AD%98%E5%91%A8%E6%9C%9F%EF%BC%88SLC%EF%BC%89%E5%8F%8A%E8%BD%AF%E4%BB%B6%E5%B7%A5%E7%A8%8B%E6%A8%A1%E5%9E%8B%EF%BC%88imp%EF%BC%89)
* **简要说明软件项目管理的过程,以及包括的主要管理活动有哪些。**
* 项目启动
* 确定项目范围
* 组件项目团队
* 建立项目的基础设施
* 项目规划
* 确定项目活动
* 预算项目成本
* 制定进度计划
* 项目实施
* 监控项目执行
* 管理项目风险
* 控制项目变更
* 项目收尾
* 客户验收项目
* 安装培训软件
* 总结项目经验
* **在选择人员进行软件项目开发时,通常应该考虑哪些因素?请列举几个。**
* 项目需求
* 待解决问题的难度
* 待开发软件系统的规模
* 待开发软件系统的技能要求
* 交付日期的严格程度
* 个人能力
* 应用领域经验
* 开发平台经验
* 编程经验
* 沟通与团队协作能力
* **软件风险管理主要包括哪些基本活动,并简述各自的主要任务是什么?**
* 风险识别:识别项目中有哪些已知的和可预测的风险。通过分析项目风险产生的各种原因,以确定风险事件及其来源
* 风险评估:对已识别的软件风险进行估计和评价,主要是两方面:估计风险发生的可能性或概率;估计风险发生所带来后果的严重程度
* 风险规划:制定具体的风险应对策略,以处理项目风险
* 风险监控:贯穿于软件开发的全过程,是一种项目跟踪活动(对风险事件的发生情况及其来源(风险源)进行监控)
* **软件需求具体包括哪些类型,请举例说明。**
* 业务需求
* 用户需求
* 功能需求
* 非功能需求
* 约束条件
* 业务规则
* 外部接口需求
* 数据定义
* **简述需求工程过程都包括哪些基本活动?每项活动的主要任务是什么?**
* 需求获取:通过各种手段,开发、捕获和修订用户的需求
* 需求分析:对收集到的需求进行提炼、分析,为最终用户所看到的软件系统建立概念化(只考虑系统外部特征,不考虑系统内部实现细节)的分析模型
* 需求规格说明:将需求开发的结果按照规定格式用文档形式进行描述,即撰写软件需求规格说明书(SRS)
* 需求验证:通过评审方式,验证需求规格说明的有效性,并及时修订
* 需求管理:在需求基线形成之后有效地控制需求变更的过程,以处理不断变化的需求约定
* **什么是需求基线?**
* **评审通过后的**软件需求规格说明书(SRS)
* **试举出几种常用的需求获取技术。**
* 面对面访谈
* 需求讨论会
* 现场观察/体验
* **简述两层C/S结构中胖客户端模型与瘦客户端模型的主要区别。另外,B/S作为三层C/S风格的一种实现方式,请图示出它的结构。**
* 瘦客户机/胖服务器:客户机只作为显示端使用,信息全部在服务器上处理。客户机所具有的处理能力在该模型中得不到充分的发挥
* 胖客户机/瘦服务器:能够利用客户机的处理能力,比瘦客户端结构在分布处理上更有效。但却使系统的维护和升级比较困难
* ![](https://pic-static.yilantingfeng.site/imgs/2022/05/26/11-41-59-f7592bd4366df6f256ea2835292adbb5-20220526114158-15c2bf.png)
* **什么是基于集群的C/S或B/S物理分布,从系统设计的角度考虑,其主要优点有哪些?**
* 将应用逻辑层(或数据层)分布在多台服务器上,形成基于集群的物理分布模式
* 有助于提高服务器并发处理的性能,以改善系统的运行速度(并发模式);提高系统的可靠性与可用性(冗余模式)
* **如何理解模块独立性,一般用什么指标来衡量模块独立性。**
* 模块独立性是软件系统划分模块时的一个主要准则,也是评价模块构造是否合理的主要标准之一
* 通常使用模块本身的内聚性和模块之间的耦合性来衡量模块独立性。内聚性越高,耦合性越低,说明模块的独立性越好
* **什么是软件测试中的错误群集现象。**
* 在测试中,对于已发现的错误数量较多的程序模块,其残留的错误数量也可能较多
* **简述单元测试环境中驱动模块和桩模块的作用。**
* 用驱动模块和桩模块来模拟与被测模块相关联的其它模块,从而构成被测模块的**单元测试环境**
* 驱动模块:用于模拟被测模块的上一级模块,即驱动模块调用被测模块
* 桩模块:用于模拟被测模块的下一级模块,即被测模块调用桩模块
* **简述黑盒测试方法和白盒测试方法的主要区别。**
* 黑盒测试:不考虑被测程序的内部逻辑结构,只按照被测程序的功能规格说明来设计测试用例。侧重于开发结果,多用于确认测试
* 白盒测试:根据被测程序的内部逻辑结构来设计测试用例。侧重于程序逻辑,多用于单元测试
* **在OOA中,试阐述你对用例的理解。**
* 用例代表目标系统向外所提供的一个完整服务或功能。主要用于从用户的角度获取系统的功能需求
* **在OOA中,分析类包括那几种类型,分别简述各自的含义。**
* 边界类:描述系统外部的角色与系统之间的交互接口
* 实体类:对应现实世界中的"事物"
* 控制类:描述用例所具有的事件流的执行逻辑。控制类本身不处理具体的任务,而是调度其它类来完成具体任务(控制类接收由边界类收集上来的信息或指令,然后根据用例的执行逻辑,再将具体任务分发给不同的实体类去完成)
* **简述软件维护的三种主要类型?**
* 改正性维护:修复开发时未能测试出来的错误
* 适应性维护:适应外部运行环境的升级变化
* 完善性维护:扩充软件功能、增强软件性能以满足用户新的需求
* **简述什么是软件的可维护性,它通常与软件的哪七种特性有关?**
* 指维护人员进行软件维护活动时的难易程度
* 七种特性
* 可理解性
* 可测试性
* 可修改性
* 可靠性
* 可移植性
* 可重用性
* 效率