星期五晚上的软件工程的老师讲得没什么趣味,还讲得乱,我还不如自己学
以下为详细的复习要点,如果要简化版,可以看 软件工程(第三版)期末复习
考完感想:各种图是最重要的,同时要记一下各个英语的全拼,然后记一下结构化与面向对象的不同。这样应该可以考60分吧~
第一章 软件工程学概论
为什么要设立该学科?
软件危机:
- 对软件开发成本和进度的估计常常很不准确
- 软件产品的质量达不到要求
- 用户对已完成的软件系统不满意
- 软件中没有适当的文档资料
- 软件成本在计算机系统总成本所占的比例逐年上升
- 软件开发生产率提高的速度不能满足需求的增长
什么是软件工程
有三个定义:
- 书上的:软件工程是指导计算机软件开发和维护的一门工程学科,采用工程的概念、原理、技术和法昂发来开发与维护软件,把经过时间考验证明正确的管理技术和当前能够得到的最好的技术方法结合起来,以经济地开发出高质量的软件并有效地维护它。这就是软件工程
- NATO会议:建立并使用完善的工程化原则,以较经济的手段获得能在实际机器上有效运行的可靠软件的一系列方法。
- IEEE:
- 将系统化的、严格约束的、可量化的方法应用于软件的开发、运行和维护,即将工程化应用于软件;
- 在1中所述方法的研究
从定义中,可以发现软件工程的特点:
- 软件工程关注大程序的构造
- 软件工程的中心课题是控制复杂性
- 软件交付使用后需要经常修改
- 开发软件的效率非常重要
软件工程方法学
软件工程方法学包含三个要素:方法、工具、过程
常用的方法学有:传统方法学、面向对象方法学
软件生命周期
软件生命周期可分为:
- 软件定义
- 问题定义:要解决什么问题?
- 可行性研究:对上一个问题有可行的解决方法吗?
- 需求分析:为了解决问题,目标系统必须做什么?
- 软件开发
- 系统设计
- 总体设计:概要设计,提出抽象的解决方案
- 详细设计:将解决具体化,设计规格说明
- 系统实现
- 编码和单元测试:写出程序
- 综合测试:集成测试和验收测试
- 系统设计
-
使用维护
- 改正性维护
- 适应性维护
- 完善性维护
- 预防性维护
软件过程
软件过程:为了获得高质量软件所需要完成的一系列任务的框架,它规定了完成各项任务的工作步骤。
瀑布模型
特点:
- 强调阶段的划分顺序与依赖:①前一工作完成后才开始后一工作;②前一工作的输出文档是后一工作的输入文档
- 推迟实现的观点;
- 质量保证的观点:每个阶段都必必须完成文档并进行评审
缺点:
- 获得完善的需求规约是非常困难的;
- 难以适应快速变化需求;
快速原型模型
特点:
- 快速原型模型是不带反馈环的,软件产品的开发基本上是按线性顺序进行的。
- 原型系统已经通过与用户交互而得到验证,据此产生的规格说明正确地描述了用户需求,因此,在开发过程的后续阶段不会因为发现了规格说明文档的错误而进行较大的返工。
- 开发人员通过建立原型系统已经学到了许多东西(至少知道了“系统不应该做什么,以及怎么不去做不该做的事情”),因此,在设计和编码阶段发生错误的可能性也比较小,这自然减少了在后续阶段需要改正前面阶段所犯错误的可能性。
缺点:
- 所选用的开发技术和工具不一定符合主流的发展;快速建立起来的系统结构加上连续的修改可能会导致产品质量低下。
增量模型
特点:
- 能在较短时间内向用户提交可完成一些有用的工作的产品
- 逐步增加产品功能可以使用户有较充裕的时间学习和适应新产品,从而减少一个全新的软件可能给客户组织带来的冲击。
缺点:
- 使用增量模型的困难是,在把每个新的增量构件集成到现有软件体系结构中时,必须不破坏原来已经开发出的产品,软件体系结构必须是开放的,相比其他的开发模型需要更精心的设计。
- 从某种意义上说,增量模型本身是自相矛盾的。它一方面要求开发人员把软件看做一个整体,另一方面又要求开发人员把软件看做构件序列,每个构件本质上都独立于另一个构件。因此需要项目管理人员对全局把握的水平较高。
螺旋模型
螺旋模型(Spiral Model)的基本思想是,使用原型及其他方法来尽量降低风险。理解这种模型的一个简单方法,是把它看做在每个阶段之前都增加了风险分析过程的快速原型模型。
一个螺旋式周期:
- 确定目标,选择方案,选定完成目标的策略
- 风险角度分析该策略
- 启动一个开发阶段
- 评价前一步的结果,计划下一轮的工作
特点:
- 对可选方案和约束条件的强调有利于已有软件的重用,也有助于把软件质量作为软件开发的一个重要目标。
- 减少了多个测试(浪费资金)或测试不足(产品故障多)所带来的风险。
- 更重要的是,在螺旋模型中维护只是模型的另一个周期,在维护和开发之间并没有本质区别。
- 螺旋模型主要适用于内部开发的大规模软件项目
缺点:
- 螺旋模型的主要优势在于,它是风险驱动的。除非软件开发人员具有丰富的风险评估经验和这方面的专门知识,否则将出现真正的风险:当项目实际上正在走向灾难时,开发人员可能还认为一切正常。
喷泉模型
特点:
- 适用于面向对象方法学开发软件
- 各个开发步骤过次反复迭代,达到认识的逐步深化
第二章 可行性研究
目的
用最小的代价在尽可能短的时间内确定问题是否能够解决。
任务
- 分析问题定义,确定问题的规模和目标
- 导出系统的逻辑模型,找到可行解法,并从下面三方面研究可行性:
- 技术可行性
- 经济可行性
- 操作可行性
过程
- 复查系统规模和目标
- 研究当前正在使用的系统
- 导出新系统的高级模型
- 进一步定义问题
- 导出和评价供选择的解法
- 推荐行动方针
- 草拟开发计划
- 书写文档供审查
数据流图
用途:描绘数据在软件中流动和被处理的逻辑过程;用于交流信息的工具
组成:
画法:数据流图简介
数据字典
用途:在软件分析和设计的过程中给人提供关于数据的描述信息;作为分析阶段的工具;是开发数据库的第一步。
组成:
- 数据流
- 数据流分量
- 数据存储
- 处理
在课本中主要是数据定义,即:
- 一般信息(名字,别名,描述)
- 定义(数据类型,长度,结构)
- 使用特点(值的范围,使用频率,使用方式)
- 控制信息(来源,用户,使用它的程序,读写权限)
- 分组信息(复结构,从属结构,物理位置)
示例:
定义数据的方法
由数据元素组成数据的方法:
- 顺序:按一定顺序连接分量,符号:分量1 + 分量2
-
选择:从多个可能的元素中选一个,符号:[元素1|元素2 ……] - 重复:将分量重复 0~n 次,符号:上限{分量}下限 or $\ ^\text{上限}_\text{下限}{ \text{分量} }$
- 可选:将分量重复 0~1 次,符号:(分量)
数据元素一般是所有人都知道的东西,比如字母和数字。一般用 = 表示”定义”。下面是例子:
- 标识符 = 字母字符 + 字母数字串
成本/效益分析
成本估计
成本主要是人力消耗,下面是估算方法:
- 代码行技术:成本 = 每行代码的成本*行数 (每行代码的成本取决于软件的复杂程度和工资水)
- 任务分解技术:成本 = 所需人力(人月为单位)* 每人每月的平均工资
- 自动估计成本技术:利用相关软件
效益分析
- 货币的时间价值:时间的未来价值,即存入银行n年后的收益
- 投资回收率:使累计的经济效益等于最初投资所需要的时间
- 纯收入:比较”将钱投入软件所产生的效益”与”将钱投入银行所产生的利息”比较
- 投资回收率:已知现在的投资额 P、将来每年可以获得的经济效益 F1,F2……,假想将钱存入银行,每年获取利息后取出当年预期的经济效益,在时间等于系统寿命时,取完银行中的存款。其中”利息”就是投资回收率。公式为: $P = F_1 / (1+j) + F_2 / (1+j)^2 + \cdots + F_n / (1+j)^n$
第三章 需求分析
需求分析的任务
- 确定对系统的综合要求:
- 功能需求:系统需要提供的服务
- 性能需求:运行速度、磁盘容量、安全性
- 可靠性和可用性需求:不出 bug
- 出错处理需求:系统怎样对环境错误响应
- 接口需求:系统与它环境的格式,包括:用户接口需求、硬件接口需求、软件接口需求和通信接口需求
- 约束:系统应遵循的限制条件,包括:语言约束、硬件平台
- 逆向需求:软件不应该做什么
- 将来可能提出的要求
- 分析系统的数据要求
- 导出系统的逻辑模型:数据流图、实体-联系图、状态转换图、数据字典
- 修正系统的开发计划
与用户沟通获取需求的方法
- 访谈(情景分析技术)
- 面向数据流自顶向下求精(细化数据流图)
- 简易的应用规格说明技术
- 先初步访谈,然后开发者和用户分别写出产品需求,并约定会议的时间地点;
- 开发者在会议前还需要列出操作对象、约束条件、性能标准等;
- 会议开始,先问所有人:是否需要这个新产品,要求所有人都同意
- 展示一张组合列表供大家讨论,可以加入或删除项
- 讨论目标:针对每个议题都创建出一张意见一致的列表
- 将所有人划分成小组,每个小组为列表中的项目指定规格说明
- 向所有人展示规格说明,供大家讨论
- 确定标准,并根据会议成功起草完整的需求规格说明书
- 快速建立软件原型
分析建模与规格说明
建立三种模型:
- 数据模型:实体-联系图(下面会讲)
- 功能模型:数据流图(前面讲了)
- 行为模型:状态转换图(下面会讲)
软件需求规格说明:
- 用自然语言描述软件需求
- 用形式化说明技术描述软件需求
实体-联系图
数据规范化
范式:数据的冗杂程度,第一范式冗余最大,第五范式冗余最小。
第一范式:每个属性值都必须是原子值
第二范式:满足第一范式,并且非关键字属性由整个关键字决定(而非部分)
第三范式:满足第二范式,并且非关键字属性仅由关键字决定,而不由另一个关键字决定。
状态转换图
其他形式化的工具
验证软件需求
从下面四方面进行验证:
- 一致性
- 完整性
- 现实性
- 有效性
第四章 形式化说明技术
概述
非形式化的缺点;矛盾、二义性、含糊性、不完整性及层次混乱等问题。 形式化的优点:简介准确;可以在不同软件工程活动之间平滑过渡。
有穷状态机
Petri网
Z语言
第五章 总体设计
设计过程(待补充)
设计原理
模块化
模块是由边界元素限定的相邻程序元素的序列,程序中的过程、函数、对象都是模块。
好处:使软件结构清楚,容易设计也容易阅读和理解。
抽象
逐步求精
信息隐藏和局部化
模块独立
衡量模块独立程度的标准:
- 耦合
- 数据耦合:模块间只交换数据
- 控制耦合:传递的信息中含有控制信息
- 特征耦合
- 内聚
第六章 详细设计
根本目标:确定应该怎样具体实现所要求的系统
第七章 实现
单元测试
单元测试除了模块之外,还有:
- 驱动程序:接受测试数据,并传入模块
- 存根程序:输出
集成测试
组装:
- 非渐增式:先分别测试,后将所有模块组合成一起测试
- 渐增式:每次测试增加一个模块 * 自顶向下:先组装主程序,再加入各单元。无需驱动程序,需要存根程序。 * 广度优先 * 深度优先 * 自底向上:无需存根程序,需要驱动程序。 * 混合策略
回归测试:在加入新模块后,重新测试已加入的模块
确认测试(验收测试)
测试目的:验证软件的有效性,确认满足用户的需求。
测试人员:以用户为主
测试方法:黑盒测试
alpha测试
用户在开发者的场景进行测试
beta测试
用户自己在使用环境下测试
白盒测试
- 语句覆盖:把所有语句运行一次
- 判定覆盖:把所有判断T/F都覆盖一次
- 条件覆盖:把所有判断条件都取到可能的值
- 条件组合覆盖:条件的各种可能都组合一次
- 点覆盖:程序的执行路径必须经过流图中的每个结点一次(等同语句覆盖)
- 边覆盖:程序的执行路径必须经过每条边(等同判断覆盖)
第八章 维护
维护的分类
- 完善性维护:增加新功能或完善已有功能(占维护的一半以上)
- 改正性维护:诊断和改正程序错误
- 适应性维护:适应新的运行环境
- 预防性维护:给未来的改进奠定基础
维护的特点
- 结构化维护和非结构化维护差别很大
- 非结构化维护指软件配置的唯一成分是代码,内部文档不足。
- 结构化维护指由完整的软件配置,有内部文档。
- 结构化维护能减少精力浪费,提高维护质量
- 维护的代价很高
第九章 面向对象
UML:Unified Modeling Language 统一建模语言,又称标准建模语言。是用来对软件密集系统进行可视化建模的一种语言。
用面向对象方法开发软件,通常需要建立3种形式的模型它们分别是:
- 描述系统数据结构的对象模型——类图
- 描述系统控制结构的动态模型——状态图
- 描述系统功能的功能模型——用例图
对象模型(类图)
类图
动态模型(状态图)
- 动态模型:
- 事件跟踪图。事件跟踪图则侧重于说明系统执行过程中的一个特点“场景”(scenarios),也叫做脚本。脚本通常起始于一个系统外部的输入事件,结束于一个系统外部的输出事件。
- 状态图。状态图是一个状态和事件的网络,侧重于描述每一类对象的动态行为。状态图通过描绘系统的状态和引起系统状态转换的事件来表示系统的行为,是行为建模或动态建模的主要工具。
功能模型(用例图)
-
用例图:
- 功能:主要用于描述系统的行为及各种功能之间的关系,是描述参与者(Actor)与用例以及用例与用例之间关系的图。
- 元素:
- 参与者(Actor):也叫角色,代表系统的用户
- 系统边界(System Scope):它确定系统的范围
- 用例(Use Case):它代表系统提供的服务
- 关联(Association):它表示参与者与用例间的关系
第十章 面向对象分析的基本过程
需求陈述
建立对象模型
对象模型由以下五层组成:
- 主题层
- 类与对象层
- 结构层
- 属性层
- 服务层
建立功能模型
用途:表明系统中数据的依赖关系,以及有关的数据处理功能
组成:同第二章 数据流图相同
定义服务
对象由:
- 描述属性的数据
- 对数据的操作(服务)
组成。
需要定义的服务分为:
- 常规行为
- 对属性的读、写
- 从事件导出的操作
- 接受到消息后指定的操作
- 从数据流图中处理框对应的操作
- 每个处理框与一个或多个对象相对应
- 利用继承减少冗余操作
- 提取公共操作,建立父类
第十一章 面向对象设计
面向对象设计的准则
- 模块化:每个类都是模块
- 抽象:
- 信息隐藏
- 弱耦合
- 强内聚
- 可重用
启发规则
前人总结的一些经验:
- 设计结果要清晰易懂:
- 用词一致,做到“顾名思义”
- 使用已有的协议
- 减少消息模式的使用
- 避免模糊的定义,应从类名推测出其用途
- 一般 - 特殊结构的深度应适当
- 设计简单的类
- 避免包含过多的属性
- 有明确的定义
- 尽量简化对象之间的合作关系
- 不要提供太多的服务,一个类提供的公共服务不超过 7 个
- 使用简单的协议,消息中的参数不超过 3 个
- 使用简单的服务,可以用一个动词和一个宾语描述其功能
- 把设计变动减至最小
软件重用
重用的种类:
- 知识重用
- 方法和标准的重用
- 软件成分的重用
- 代码重用
- 源代码健特
- 源代码包含
- 继承
- 设计结果重用
- 分析结果重用
- 代码重用
软件重用的效益:
- 质量提高
- 生产率提高
- 成本下降(节省的成本为:从头开始的成本 - 软件重用的成本 - 实际总的成本)
系统分解
将系统分解为若干个子系统,有利于降低设计难度,有利于分工协作,有利于维护人员对系统的理解和维护
子系统间的交织方式:
- 客户 - 供应商关系
- 平等伙伴关系
组织系统的方案:
- 层次结构
- 块状结构
第十二章 面向对象实现
程序设计语言
面向对象语言的优点:
- 一致的表示方法
- 可重用性
- 可维护性
面向对象语言的技术特点:
- 支持类与对象概念的机制
- 实现整体 - 部分(即聚集)结构的机制
- 实现一般 - 特殊(即泛化)结构机制
- 实现属性和服务的机制
- 类型检查
- 类库
- 效率
- 持久保存对象
- 参数化类
- 开发环境
选择面向对象语言:
- 将来能否占主导地位
- 可重用性
- 类库和开发环境
- 其他因素:培训服务、技术支持、发行平台
程序设计风格
提高可重用性
- 提高方法的内聚:一个方法(服务)只实现一个功能
- 减小方法的规模
- 保持方法的一致性
- 把策略与实现分开:即一类方法负责做出决策,另一类方法负责完成具体的操作
- 全面覆盖,能正确处理各种正常值与非正常值
- 尽量不使用全局信息,降低与外界的耦合程度
- 利用继承机制
- 调用子过程
- 分解因子
提高可扩充性
- 封装实现策略
- 不要使用一个方法遍历多条关联链
- 避免使用多分支语句
- 精心确定公有方法
提高健壮性
- 预防用户的操作错误
- 检查参数的合法性
- 不要预先确定限制条件
- 先测试后优化