【笔记】《软件工程导论-第六版》复习笔记
1.概述
1.1 软件危机
1.1.1 定义
软件开发和维护过程中遇到的一系列严重问题,长期找不到解决这些问题的方法,问题逐渐积累起来,形成了尖锐的矛盾
1.1.2 产生原因
- 软件规模变大,结构更复杂
- 开发管理困难
- 开发费用增加
- 生产方式的落后
- 开发技术和工具落后
主要原因:
- 软件本身的特点
- 缺乏好的开发方法和手段
软件的定义
与计算机系统操作有关的程序、文档、数据
1.2 软件工程概念
从管理和技术两方面研究如何开发和维护好软件,具有工程性
遵循的基本原则
- 抽象
- 信息隐藏
- 模块化
- 可验证性
- 局部化
- 一致性
- 完全性
1.3 方法学三要素
-
方法
-
工具
-
过程
-
传统方法学
依次分成若干阶段,顺序地完成每阶段任务
-
面向对象
以数据为主线,把【数据 】和 【对数据的操作】 紧密结合
三大特性:
- 封装
- 继承
- 多态
1.4 软件生命周期
- 软件定义
- 问题定义
- 可行性研究
- 需求分析
- 软件开发
- 总体设计
- 详细设计
- 编码和单元测试
- 综合测试
- 软件维护:持久地满足用户的需求
1.4.1 各个阶段任务
- 问题定义:要解决的问题是什么?
- 可行性研究:有行得通的办法吗?
- 需求分析:为了解决,要做什么?
- 总体设计(概要设计):应该怎样实现?
- 详细设计(模块设计):怎样具体实现?
- 编码和单元测试
- 综合测试:集成测试+验收测试
- 软件维护:改正性、适应性、完善性、预防性
1.5 生存周期模型
1.5.1 瀑布模型
分为:计划阶段——开发阶段——运行阶段
缺点:很难动态认识软件,缺乏灵活性
1.5.2 原型模型
快速建立反应用户需求的系统,并于用户交互,不断修改需求满足用户需要
1.5.3 增量模型
又称为渐增模型
能在较短时间内向用户提交可完成部分工作的产品
主要的问题是:缺乏丰富而强有力的软件工具和开发环境
1.5.4 螺旋模型
是将瀑布模型和增量模型结合起来的软件开发模型
使用原型法和其他方法来降低风险***,每个阶段都增加了风险分析*
风险分析包括:
- 风险标识
- 风险估算
- 风险评价
- 风险驾驭和监控
适用于内部开发的***大规模软件项目***
1.5.5 喷泉模型
以用户需求为动力,以对象最为驱动模型
适用于面向对象开发方法
开发过程具有——迭代性、无间隙性
2. 可行性研究
2.1 目的
寻找有无可行的解决方案
从三个方面研究可行性
- 技术可行性
- 经济可行性
- 操作可行性
可行性研究要进行的需求分析和设计应该是——简化、压缩的
步骤:
- 复查系统规模和目标
- 研究目前正在使用的系统
- 导出新系统的高层逻辑模型(数据流图和数据字典)
- 进一步定义问题
- 导出和评价供选择的解法
- 推荐行动方针
- 草拟开发计划
- 书写文档提交审查
2.2 系统流程图
2.2.1 定义
概括地描述物理系统的工具,利用图形符号表示系统的各个元素
2.2.2 基本符号
2.3 数据流图 DFD
描绘【信息流和数据】从输入到输出所经受的交换
是运用结构化分析方法(SA)表示系统逻辑模型的工具
2.3.1 特点
-
无具体物理部件,只描绘逻辑过程
-
是系统逻辑功能的图形展示
-
只考虑系统必须完成的基本逻辑功能,不考虑如何实现
2.3.2 符号
- 正方形/ 立方体——数据源点/终点(数据外部实体)【不能被计算机处理】
- 圆角矩形/ 圆形——处理(加工)
- 开口矩形/ 两平行线——数据存储
- 箭头——数据流
2.3.3 常用绘图方法
- 自顶向下
- 分层绘制
- 逐步求精
2.4 数据字典
数据的信息的集合
数据流图 和 数据字典 构成系统的逻辑模型
2.4.1 内容
- 数据流
- 数据元素
- 数据存储
- 处理
一般不包括外部实体
2.4.2 用途
作为分析阶段的最重要的工具
2.5 成本/效益分析
从经济角度分析开发系统是否划算
2.5.1 成本估计方法
- 代码行
- 任务分解
- 自动估计成本
3. 需求分析
3.1 目的
系统必须做什么?
包括——系统主要功能、用户界面、运行环境和软件性能的描述
一般确定用户对软件的 功能需求 和 非功能需求
需求分析结束后,应写出软件需求规格说明书, 包括——数据描述、功能描述、性能描述、环境描述
3.2 对系统的综合要求
- 功能需求
- 性能需求
- 环境需求
- 用户界面需求
- 可靠性、安全性、保密性、可移植性、可维护性…
3.3 导出逻辑模型
常用方法:
- 数据流图
- E-R图
- 状态转换图
- 数据字典
3.4 结构化分析方法SA
面向数据流的自顶向下、逐步求精进行需求分析的工具
结构化分析工具:
- 数据流图
- 数据字典
- 结构化语言
- 判定表
- 判定树
3.5 实体联系图 E-R图
准确描述用户数据,建立数据模型
3.5.1 数据模型构成
- 实体——方框
- 属性——圆角框
- 联系——菱形
3.6 状态转换图
用来表示系统的行为,反映了状态与事件间的关系,强调对象行为的事件顺序
状态图的符号:
- 初态——实心圆
- 终态——同心圆
- 中间状态——圆角矩形
3.7 其他图形工具
3.7.1 层次方框图
描述数据的层次结构
3.7.2 Warnier 图
表示信息的层次结构,用树形结构描绘信息, 表明信息的逻辑组织
3.8 用于需求分析的软件工具——PSL/PSA系统
PSL——描述系统的形式语言
PSA——处理PSL描述的分析程序
优点
- 改进文档质量,具有完整性、一致性、无二义性,从而减少管理和维护费用
- 数据存于数据库,便于增删改
4. 总体设计
4.1 目的
系统应该如何实现?
总体设计又称为——概要设计
4.2 步骤
- 寻找不同方案, 需求分析阶段的数据流图设想可能的方案
- 选择若干可行方案,准备系统流程图,进行成本/效益分析
- 进行必要的数据库设计,确定测试要求并列出测试计划
- 最后对结果进行审查
4.3 设计原理
- 抽象
- 模块化
- 逐步求精
- 信息隐藏和局部化
- 是模块内包含的信息(过程和数据),对于不需要的模块来说是不能访问的
- 模块独立
- 是模块化、抽象、信息隐藏和局部化的直接结果
- 衡量模块独立性的标准——耦合和内聚
4.4 耦合
不同模块之间彼此连接的紧密程度
分类:
- 完全独立
- 数据耦合————低耦合
- 两模块仅仅交换数据
- 控制耦合————中等耦合
- 通过参数交换信息,参数包含控制信息(如开关量、标志等)
- 特征耦合
- 公共环境耦合
- 两个模块共享全局的数据区域
- 标记耦合
- 两模块传递数据结构
- 内容耦合—————最高耦合,应避免
- 出现了下列情况之一
- 访问另一模块的内部数据
- 不通过正常入口进入另一模块
- 两模块部分代码重叠
- 一个模块多个入口
- 出现了下列情况之一
4.5 内聚
一个模块内彼此结合的紧密程度,即模块的功能强度
往往高内聚就意味着松耦合
分类:
低内聚 | 中内聚 | 高内聚 |
---|---|---|
偶然内聚(最差) | 过程内聚 | 顺序内聚 |
逻辑内聚 | 通信内聚 | 功能内聚(最好) |
时间内聚 |
4.6 描绘软件结构的图形工具
4.6.1 层次图
描述软件的层次结构
矩形————模块
连线————调用关系
4.6.2 HIPO图
可追踪性:除了最顶层方框之外,每个方框都加了编号
4.6.3 结构图
进行软件结构设计的有力工具,着重反映模块间的调用关系和层次关系
主要内容
- 模块(方框表示)
- 模块间的控制信息(箭头尾部实心圆)
- 模块间的数据信息(箭头尾部空心圆)
- 模块间的信息传递(带注释的箭头)
- 直线表示调用关系
4.7 结构化设计方法SD
结构化设计方法 ,面向数据流设计方法,是把数据流图中的信息流映射成软件结构
4.7.1 信息流的类型
-
交换流:
信息沿输入通路进入系统,同时由外部形式变换成内部形式,进入系统的信息通过变换中心,经加工处理以后再沿输出通路变换成外部形式离开软件系统
当数据流图具有这些特征时,这种信息流就叫作变换流
从而有了交换型分析设计,过程为输入(不止一个)——变换——输出
-
事务流:
数据沿输入通路到达一个处理 T,这个处理根据输入数据的类型在若干个动作序列中选出一个来执行
这类数据流应该划为一类特殊的数据流,称为事务流
某个加工(事务处理中心)将输入流(只有一个)分离成许多发散的数据流,形成许多加工路径,并根据输入值选择其中一条路径
区分:
- 变换流是一个线性的处理
- 事务流是一个分类处理
4.7.2 转换步骤
将数据流图转换为软件结构:
- 确定信息流的类型
- 划定流界
- 将数据流图映射为程序结构;
- 提取层次控制结构
- 通过设计复审和使用启发式策略进一步精化所得到的结构
5. 详细设计
5.1 目的
怎样具体地实现所要求的系统
详细设计出程序的“蓝图”,对模块内的算法和数据结构进行设计
5.1.1 基本任务
- 数据结构设计
- 算法设计
- 数据库物理设计
- 界面设计
- 其他设计
- 编设设计说明书
- 评审——以提高软件质量为目标
5.2 结构化设计
5.2.1基本方法
- 逐步求精法
- 自顶向下法
5.2.2 三种控制结构
- 顺序
- 选择
- 循环
5.2.3 定义
主要强调程序易读性
每个代码块只有一个入口,一个出口
尽可能少用goto语句
5.3 过程设计的工具
简单分为:图形、表格、语言
5.3.1 程序流程图
使得程序员过早考虑程序流程控制,不考虑程序的全局结构
不容易表示模块的层次结构
环形复杂度计算公式:
5.3.2 盒图(N-S图)
不可能任意转移控制,符合结构化规则
特点:
②盒图没有箭头,因此不允许随意转移控制。
③很容易确定局部和全程数据的作用域
④很容易表现嵌套关系,也可以表示模块的层次结构
5.3.7 IPO图
【输入、处理、输出图】的简称,能够方面描述输入数据、对数据的处理、输出数据之间的关系
记录了**【算法】**的简单描述
5.3.3 PAD图——问题分析图
二维树形结构来表示程序的控制流,设计出来的为结构化程序
优点:
①使用PAD符号设计的程序必然是结构化程序。
② PAD图所描绘的程序结构十分清晰。最左面的竖线是程序的主线,即第一层结构。随着程序层次的增加,PAD 图逐渐向右延伸。每增加一个层次,图形向右扩展一条竖线。图中竖线的总条数就是程序的层次数。
③PAD图表现的程序逻辑,易读、易懂、易记,程序从图中最左竖线上端的结点开始执行,自上而下,从左向右顺序执行,遍历所有结点。
④ 容易将PAD图转换成高级语言源程序,这种转换可用软件工具自动完成。
⑤ 既可表示程序逻辑,也可描绘数据结构。
⑥ 支持自顶向下、逐步求精方法的使用。
5.3.4 判定表
可以清晰地表示复杂的条件组合和应做动作之间的关系
并非通用的设计工具
四部分组成
- 左上部列出所有条件
- 左下部是所有可能做的动作
- 右上部是表示各种条件组合的矩阵
- 右下部是和每种条件组合对应的动作
5.3.5 判定树
判定表的变种,常见的系统分析和设计的工具
5.3.6 过程设计语言PDL
即伪码,描述模块算法设计和处理细节的语言
用正文形式表示数据和处理过程的设计工具
5.4 面向数据结构的设计方法
5.4.1 Jackson图
【Jackson图】和【Warnier图】是最著名的两个面向数据结构的设计方法,以及JSp方法
5.4.2 Jackson方法
适用于规模适中的数据处理系统的开发
5个步骤
-
分析确定输入输出逻辑结构,用jackson图描绘数据结构
-
找出有对应关系的数据单元
-
下列3条规则从描绘【数据结构】的jackson图导出到描绘【程序结构】的jackson图
-
列出所有操作、条件
-
伪码表示
5.5 程序复杂程度
5.5.1 McCabe方法
又称为【环路度量】
流图实质上是“退化的”程序流程图,仅仅描绘程序的控制流程
针对面向软件产品的运行、修正、转移
5.5.2 Halstead方法
根据程序中运算符和操作数的总数来度量
5.5.3 McCAll质量模型
质量因素:
- 正确性、健壮性、效率、完整性(安全性)、可用性、风险、可理解性、可维修性、灵活性(适应性)、可测试性、可移植性、可再用性、互运行性
6. 实现
6.1 目的
编写代码 + 测试
本阶段是对设计的进一步具体化,并保证软件质量(软件质量必须在设计与实现过程中予以保证)
6.2 白盒测试
又称为【结构测试】,完全知道程序的结构和处理算法
按照程序内部的逻辑测试程序,检测程序中的主要执行通路是否按照预期工作
在测试过程的【早期】进行
测试技术:
-
逻辑覆盖:
语句覆盖 使被测程序中每个语句至少执行一次 判定覆盖 不仅每个语句必须至少执行一次,而且每个分支都至少执行一次 条件覆盖 不仅每个语句至少执行一次,而且使判定表达式中的每个条件都取到各种可能的结果 判定/条件覆盖 使得判定表达式中的每个条件都取到各种可能的值,而且每个判定表达式也都取到各种可能的结果 条件组合覆盖 使得每个判定表达式中条件的各种可能组合都至少出现一次 点覆盖 使得程序执行路径至少经过流图的每个结点一次 边覆盖 使得程序执行路径至少经过流图中每条边一次 路径覆盖 使程序的每条可能路径都至少执行一次(如果程序图中有环,则要求每个环至少经过一次) -
控制结构测试(顺序,分支,循环)
-
基本路径测试
6.3 黑盒测试
又称为【功能测试】,完全不知道程序的内部结构和处理过程
在程序接口进行测试,检查程序是否按照规格说明书的规定正常使用
站在用户的角度,着重测试【软件功能】
在测试过程的【后期】
测试技术:
-
等价划分
步骤:等价类划分——确定测试用例
-
边界值分析
-
错误推测
-
因果图
6.4 测试步骤
-
单元测试(模块测试)
将【每个模块】作为独立实体进行测试
-
子系统测试
经过单元测试的模块放在一起形成【子系统】来测试,着重测试模块接口
-
系统测试
将子系统装配成【完整系统】来测试,为了发现性能、质量不合要求的错误
【注】:2 + 3 统称为集成测试
-
确认测试(验收测试)
使用实际数据测试,验证是否满足用户需求
-
平行运行
测试阶段的信息流
6.5 单元测试(模块测试)
和【编码】属于同一阶段,为了发现编码错误
使用【白盒测试】技术
测试重点:
- 模块接口
- 局部数据结构
- 重要执行通路
- 出错处理通路
- 边界条件:边界测试是单元测试最重要任务
6.6 集成测试
为了发现模块接口错误
两种方法:
非渐增式:先分别测试每个模块,再合起来
渐增式:把下一个要测试的模块和测好的一起测,每次加一个
渐增式集成策略:
-
自顶向下(深度优先、宽度优先)
优点:不需要测试驱动、早期能验证主要功能、早期发现上层模块接口错误
缺点:需要存根程序、底层发现的晚、早期无法展开人力
-
自底向上(最底层模块开始)
测试开销更小
但需要测试驱动,较晚验证主要功能
6.7 确认测试(验收测试)
为了发现功能错误
验证软件【有效性】
使用【黑盒测试】方法
对应的是【需求分析阶段】
6.8 调试
调试是在测试发现错误之后排除错误的过程
途径:
- 蛮干法
- 回溯法
- 排除法
- 演绎法
- 归纳法
6.9 软件可靠性
表现在软件的正确性和健壮性
可靠性定义————在给定时间间隔内,按照规格说明书的规定成功运行的概率
可用性定义————在给定的时间点,按照规格说明书的规定,成功地运行的概率
区别
- 可靠性意味着在 0到 t 这段时间间隔内系统没有失效
- 而可用性只意味着在某一时刻 t,系统是正常运行的
软件可靠性的定量指标—————能够以数字概念描述可靠性的数学表达式中使用量
MTTF:平均无故障时间
MTTR:平均维修时间
7. 维护
7.1 目的
提高软件的可维护性,减少软件维护的工作量
7.2 步骤
确定维护类型——改正性维护从评价错误的严重性开始——适应性和完善性维护——实施维护
7. 分类
- 改正性维护
- 适应性维护
- 完善性维护(由于开发时的不彻底、不完全造成的)
- 预防性维护
7.4 软件的可维护性
软件可维护性时值软件能够被理解、改正、适应和增强功能的容易程度
- 可理解性:表现为外来读者理解软件的结构、功能、接口和内部处理过程的难易程度
- 可测试性:诊断和测试的容易程度取决于软件容易理解的程度(与可理解性相互促进)
- 可修改性:耦合、内聚、信息隐藏、局部化、控制域、作用域等影响可修改性
- 可移植性:将程序从一台计算机移动到另一台计算机环境的难易程度
- 可重用性:同意书五不做修改或稍加修改即可在不同环境重复使用
文档是软件可维护性的决定因素
7.5 软件再工程过程
- 库存目录分析
- 文档重构
- ****
- 代码工程
- 数据重构
- 正向工程
7.6 维护的副作用
编码副作用、数据副作用、文档副作用
性
可靠性定义————在给定时间间隔内,按照规格说明书的规定成功运行的概率
可用性定义————在给定的时间点,按照规格说明书的规定,成功地运行的概率
区别
- 可靠性意味着在 0到 t 这段时间间隔内系统没有失效
- 而可用性只意味着在某一时刻 t,系统是正常运行的
软件可靠性的定量指标—————能够以数字概念描述可靠性的数学表达式中使用量
MTTF:平均无故障时间
MTTR:平均维修时间
7. 维护
7.1 目的
提高软件的可维护性,减少软件维护的工作量
7.2 步骤
确定维护类型——改正性维护从评价错误的严重性开始——适应性和完善性维护——实施维护
7. 分类
- 改正性维护
- 适应性维护
- 完善性维护(由于开发时的不彻底、不完全造成的)
- 预防性维护
7.4 软件的可维护性
软件可维护性时值软件能够被理解、改正、适应和增强功能的容易程度
- 可理解性:表现为外来读者理解软件的结构、功能、接口和内部处理过程的难易程度
- 可测试性:诊断和测试的容易程度取决于软件容易理解的程度(与可理解性相互促进)
- 可修改性:耦合、内聚、信息隐藏、局部化、控制域、作用域等影响可修改性
- 可移植性:将程序从一台计算机移动到另一台计算机环境的难易程度
- 可重用性:同意书五不做修改或稍加修改即可在不同环境重复使用
文档是软件可维护性的决定因素
7.5 软件再工程过程
- 库存目录分析
- 文档重构
- ****
- 代码工程
- 数据重构
- 正向工程
7.6 维护的副作用
编码副作用、数据副作用、文档副作用