软件工程复习(张海藩版)
第一章 软件工程学概述
软件危机
产生原因
客观原因:
- 软件是逻辑部件,缺乏可见性,难以管理和控制;
- 软件较难维护;
- 软件规模庞大,程序复杂度随软件规模增加指数上升。
主观原因:
- 对软件开发和维护有很多错误认知和做法;
- 对用户要求没有完整准确的认识就匆忙着手于写程序;
- 开发人员只重视程序而忽视软件配置的其余成分;
- 轻视维护。
消除途径
- 采用合适的软件开发方法;
- 建立良好的需求管理;
- 引入严格的质量控制;
- 采用合适的工具和技术;
- 加强沟通和协作;
- 提供持续的培训和学习机会;
- 管理项目风险;
- 投资于软件质量和可维护性。
软件工程基本原理
- 用分阶段的生命周期计划严格管理;(分阶段)
- 坚持进行阶段评审;(坚评审)
- 实行严格的产品控制;(严品控)
- 采用现代程序设计技术;(用现技)
- 结果应能清楚地审查;(果清查)
- 开发小组的人员应该少而精;(人少精)
- 承认不断改进软件工程实践的必要性。(认践必)
软件工程方法学
三要素
方法:软件开发“如何做”的技术
工具:自动或半自动的软件支撑环境
过程:软件开发各个阶段要完成什么
传统方法学
优点:
- 把软件周期划分成若干相互独立、简单的阶段,便于不同人员分工协作;
- 开发过程中采用了科学的管理技术和良好的技术方法,在每个阶段结束之前都进行严格审查,保证了软件质量,提高了软件的可维护性;
- 大大提高了软件开发的成功率和生产率。
缺点:
- 不适合软件规模庞大、软件需求模糊需要不断变更的情况;
- 把数据和操作人为地分离成两个独立的部分,增加了软件开发与维护的难度。
面向对象方法学
要点:
- 把对象作为融合了数据和操作的统一的软件构件;
- 把所有对象都划分成类;
- 继承性;
- 对象间能通过发送消息互相联系。
优点:
- 降低了软件产品的复杂性;
- 提高了软件的可理解性;
- 简化了软件的开发和维护工作;
- 提高了软件的可重用性。
与传统方法学比:
- 传统方法学强调自顶向下、逐层分解、顺序开发;
- 面向对象方法学强调主动多次反复迭代地开发,保证了各项开发活动之间的平滑过渡。
软件生命周期(3+8)🔺
软件定义
问题定义
可行性研究
需求分析
软件开发
总体设计
详细设计
编码和单元测试
综合测试
运行和维护
软件维护
软件模型
瀑布模型
特点
- 阶段间具有顺序性和依赖性
- 推迟实现的观点
- 质量保证的观点
优点
- 可强迫开发人员采用规范的方法
- 严格地规定了每个阶段必须提交的文档
- 要求每个阶段交出的所有产品都必须经过质量保证小组的仔细验证
- 对文档的约束,是软件维护变得容易一些,且能降低软件预算
缺点
- 瀑布模型是由文档驱动的
- 缺乏对于需求变更和项目变化的适应性
适用
在开发的早期阶段软件需求被完整确定
快速原型模型
特点
通过实践完善需求,以减少开发风险和需求不确定性
缺点
- 原型系统的内部结构可能不好
- 开发人员需要掌握建立快速原型的开发技术和工具
适用
- 需求快速变化
- 中小型交互系统
- 大型系统的用户界面
- 生命周期较短的系统
增量模型
特点
将软件项目构件化,将软件产品分批次提交给用户
优点
- 能在较短的时间内向用户提交能完成部分功能的产品
- 逐步增加产品功能可以使用户有较充裕的时间学习和适应新产品
- 重要功能被首先交付,从而使其得到最多的测试,降低开发风险
缺点(技术难点)
- 要求软件体系结构必须是开放的
- 本身自相矛盾,把产品既看作整体又看作相互独立的部分
- 容易变成边做便该模型,使软件开发过程失去整体性
螺旋模型
特点
每个阶段之前都增加了风险分析过程的快速原型模型
优点
- 有利于已有软件的重用,有助于把软件质量作为软件开发的目标
- 减少了过多测试或测试不足所带来的风险
- 在螺旋模型中维护只是模型的另一个周期,在维护和开发之间并没有本质区别
缺点(技术难点)
- 螺旋模型使风险驱动的,是优点也是弱点
- 要求软件开发人员具有丰富的风险评估经验和这方面的专门知识
喷泉模型
特点
以用户需求为动力,以对象为驱动的模型,适合于免修对象的开发方法
- 迭代:各阶段间迭代,一个阶段内步骤迭代
- 无缝:各阶段之间无缝衔接
- 小维护:采用面向对象范型后维护时间缩短了
第二章 可行性研究
可行性分析
经济可行性
技术可行性
操作可行性
数据流图🔺
矩形:数据的源点/终点
椭圆:处理
不封口矩形:数据存储
带箭头的直线:数据流(线上只能写名词)
数据字典🔺
数据字典的内容
- 数据流
- 数据流分量(数据元素)
- 数据存储
- 处理
数据字典的实现
每张卡片主要应该包含名字、别名、描述、定义、位置
第三章 需求分析
需求分析
内容
功性靠出口
- 功能需求
- 性能需求
- 可靠性需求
- 出错处理需求
- 接口需求
- 约束
- 逆向需求
- 未来可能提出的需求
获取需求的方法
- 访谈;
- 面向数据流自顶向下求精;
- 简易的应用规格说明技术;
- 快速建立软件原型。
状态转换图🔺
一张状态图里只能有一个初态,终态可以有0至多个
初态:实心圆
终态:同心圆
实线上方写事件
实体联系图
第五章 总体设计
设计原理🔺
- 模块化
- 抽象
- 逐步求精
- 信息隐藏和局部化
- 模块独立
启发规则
- 改进软件结构提高模块独立性
- 模块规模应该适中
- 深度、宽度、扇出和扇入应该适中
- 模块的作用域应该在控制域之内
- 争降低模块接口的复杂程度
- 设计单入口单出口的模块
- 模块功能应该可以预测
层次方框图🔺
HIPO图🔺
IPO图是输入、处理、输出图的简称:三列长矩形,双线三角箭头
软件体系结构图
面向数据流设计方法🔺🔺
面向数据流的设计方法把信息流映射成软件结构
信息流有两种类型:
- 变换流:外部进入,以外部形式离开
- 事务流:以事务为中心
数据流图转换成软件结构图:
- 确定输入输出流边界,孤立出变换中心
- 第一级分解:1) 顶层控制模块 2) 输入、变换、输出模块
- 第二级分解:把每个处理映射成一个适当的模块
第六章 详细设计
程序流程图🔺
开始、结束:圆角矩形
处理:矩形
循环:分上界、下界,缺角矩形
选择:菱形
盒图🔺
PAD图🔺
判定表
上半部分:左:列出所有条件
右:T条件成立,F条件不成立,空白表示不影响
下半部分:左:所有可能的动作
右:×表示做这项动作,空白表示不做这项动作
判定树
Jackson图
逻辑结构:
- 顺序结构
- 选择结构(条件右上角有小圆圈)
- 重复结构(条件右上角有星号)
不易翻译成程序,不易在横式打印机输出
环形复杂度🔺
计算方法
- 环形复杂度=流图中线性无关的区域
- 环形复杂度=边数 - 结点数 +2
- 环形复杂度=判定结点的数目 + 1
第七章 实现
白盒测试(结构测试)🔺
逻辑覆盖
语句覆盖
每条语句至少执行一次
判定覆盖(分支覆盖)
每条判定至少取true或false各一次
条件覆盖
每条语句至少执行一次
判定表达式中的每个条件都取到各种可能结果
判定/条件覆盖
判定表达式中的每个条件都取到各种可能结果
每条判定至少取true或false各一次
条件组合覆盖
判定表达式中的条件的各种可能组合至少出现一次
点覆盖
边覆盖
路径覆盖
每条路径至少执行一次
有环要求每个环至少经过一次
设计测试用例🔺🔺
用例格式:输入a,b,x 输出a,b,x
语句覆盖
用例:
[(2,0,4), (2,0,3)]
判定覆盖
用例:
[(2,0,4), (2,0,3)]
[(1,1,1), (1,1,1)]
条件覆盖
满足以下覆盖情况:
a>1 a<=1 b==0 b≠0
a==2 a≠2 x>1 x<=1
用例:
[(2,0,4), (2,0,3)]
[(1,1,1), (1,1,1)]
判定/条件覆盖
用例:
[(2,0,4), (2,0,3)]
[(1,1,1), (1,1,1)]
判定/条件覆盖不一定比条件覆盖强
条件组合覆盖
满足以下覆盖情况:
a>1 b0 与 a2 x>1
a>1 b≠0 a==2 x<=1
a<=1 b==0 a≠2 x>1
a<=1 b≠0 a≠2 x<=1
用例:
[(2,0,4), (2,0,3)]
[(2,1,1), (2,1,2)]
[(1,0,3), (1,0,4)]
[(1,1,1), (1,1,1)]
路径覆盖
用例:
a=1, b=1, x=1
a=1, b=1, x=2
a=3, b=0, x=1
a=2, b=0, x=1
黑盒测试(功能测试)🔺
等价划分
划分等价类
按照输入条件划分有效等价类和无效等价类
例:
每个学生可选三门课
有效等价类:选修1-3门课
无效等价类:未选修或选修3门以上
选择测试用例
使一个测试用例尽可能覆盖多个有效等价类
一个测试用例只能覆盖一个无效等价类,每个无效等价类都需要测试用例
边界值分析
选取的测试用例应该刚好等于、刚刚小于、刚刚大于边界值
例子:
- 输入文件可有1-255个记录
设计用例:文件记录数为0,1,255,256
- 检索文件摘要,最多4篇
设计用例:0,1,4,5
- 输入/输出有序集(数据结构)的边界
设计用例:第一个和最后一个元素
第八章 维护
分类
改正性维护
为诊断和改正系统中的隐藏错误
适应性维护
为配合变化了的环境适当地修改
完善性维护
为满足用户增加、改进已有功能
预防性维护
为改进未来的可维护性和可靠性
维护阶段的文档
软件问题报告
第九章 面向对象方法学引论🔺
面对对象建模
对象模型(最基本最重要)
描述系统静态结构
类图
类与类间的关系:
- 关联:实线,0…1 0…* / * 1…* / 1+ 1…15 3
- 聚集:共享聚集:空心菱形实线,部分对整体影响不大
组合聚集:实心菱形实线,部分缺失影响整体
部分——>整体
-
泛化(继承):空心三角形实线,子——>父
-
依赖:实心三角形虚线,使用者——>被使用者
细化:空心三角形虚线,更详细的——>抽象层次低的
动态模型
功能模型
通常,功能模型由一组数据流图组成
用例模型
用用例模型建立起来的系统模型称为用例模型
用例图包含的模型元素:
- 系统:一个里面放用例的矩形框,行为者放在框外
- 用例:被行为者启动的完整功能,一个椭圆
- 行为者:与系统交互的人或者其他系统,代表外部实体,一个小人,与用例实线连接(没箭头)
用例之间的关系:
- 扩展关系:空心三角形实线,线上写“扩展”,特殊指向一般,指向被扩展的
- 使用关系:空心三角形实线,线上写“使用”,整体指向部分,指向被使用的
用例图
三种模型的关系
对象模型定义了做事情的实体(对象)
功能模型指明了系统应该做什么(方法)
动态模型明确规定说明时候做(调用顺序)
第十章 面向对象分析(OOA)🔺
对象模型
三个子模型
- 对象模型(静态结构)
- 动态模型(交互次序)
- 功能模型(数据变换)
五个层次
- 主题层
- 类与对象层
- 结构层
- 属性层
- 服务层
活动图
顺序图
第十一章 面向对象设计(OOD)🔺
面向对象设计准则
- 模块化
- 抽象
- 信息隐藏
- 弱耦合:交互耦合,继承耦合
- 强内聚:服务内聚,类内聚,一般-特殊内聚
- 可重用
启发规则
- 设计结果应该清晰易懂
- 一般-特殊结构的深度应该适当
- 设计简单的类
- 使用简单的协议
- 使用简单的服务
- 把设计变动减至最小
软件重用
软件重用的层次
- 知识重用
- 方法和标准的重用
- 软件成分的重用
软件成分的重用级别
- 代码重用
- 设计结果重用
- 分析结果重用
典型的可重用成分
- 项目计划
- 成本估计
- 体系结构
- 需求模型和规格说明
- 设计
- 源代码
- 用户文档和技术文档
- 用户界面
- 数据
- 测试用例
可重用软构件应该具备的特点
- 模块独立性强
- 具有高度可塑性
- 接口清晰、简明、可靠
系统分解
面向对象数据模型逻辑上由四大部分组成,对应组成目标系统的4个子系统
- 问题域子系统
- 人机交互子系统
- 任务管理子系统
- 数据管理子系统
第十三章 软件项目管理
估算软件规模🔺
代码行技术
L = ( 最小规模 + 4×最可能规模 + 最大规模)/ 6
单位:行代码数(LOC),千行代码数(KLOC)
功能点技术
信息域的五个特性
- 输入项数(Inp)Input
- 输出项数(Out)Output
- 查询数(Inq)Inquire
- 主文件数(Maf)Main file
- 外部接口数(Inf)Interface
估算功能点的步骤
- 计算未调整的功能点数 UFP :UFP = a1×Inp + a2×Out + a3×Inq + a4×Maf + a5×Inf
- 计算技术复杂度因子 TCF :DI = Fi累加和
TCF = 0.65 + 0.01×DI
- 计算功能点数 FP:FP = UFP×TCF
工作量估量🔺
工作量是软件规模的函数,单位是人月(pm)
静态单变量模型
软件规模单位是KLOC
动态多变量模型
软件规模单位是LOC
COCOMO2模型
E = a × KLOC的b次方×fi的累乘
进度计划🔺
甘特图
工程网络图
最早时刻 EET Early
最早时刻是开始向结束推(从前往后)
最迟时刻 LET Lately
最迟时刻是结束向开始推(从后往前)
关键路径
路径上的总事件持续时间最大的是关键路径