软件制造工程学习笔记
- 第一章 软件工程学概述
-
- 软件危机
- 软件工程
- 第二章 软件设计基本概念
-
- 设计过程
- 设计原理*
-
- 模块化
- 抽象
- 第三章 详细设计
-
- 结构程序设计
- 人机界面设计
- 过程设计工具
-
- 程序流程图
- 盒图(N-S图)
- PAD图
- 判定表
- 判定树
- 过程设计语言(PDL)
- 面向数据结构的设计方法
-
- Jackson图
- 改进的Jackson图
- Jackson方法
- 程序复杂度的定量度量
-
- McCabe方法
- Halstead方法
- 小结
- 第四章 软件编码
-
- 选择程序设计语言
- 代码规范
-
- 代码组织与风格
- 注释
- 命名
- 声明
- 语法结构
- 代码版本控制(SVN)
- 第五章 软件测试
-
- 软件测试基础
-
- 目标
- 准则
- 方法
- 测试步骤
- 测试阶段的信息流
- 单元测试
-
- 代码审查
- 计算机测试
- 集成测试
- 确认测试
- 白盒测试
-
- 逻辑覆盖
- 控制结构测试
- 黑盒测试技术
-
- 等价划分
第一章 软件工程学概述
软件危机
- 典型表现
- 对软件的开发成本和进度的估计常常很不准确
- 用户对“已完成的”软件系统不满意的现象经常发生
- 软件产品的质量往往靠不住
- 软件常常是不可维护的(难以或无法添加新功能)
- 软件通常没有适当的文档资料
- 软件成本在计算机系统总成本中所占的比例逐年上升
- 软件开发生产率的提高速度远赶不上软件需求的提高速度
- 产生原因
- 与软件本身特点有关
- 软件是逻辑部件
- 软件不会被“用坏”,如果发现了错误,很可能是开发时期引入
- 软件规模爆发,而且程序复杂性将随着程序规模的增加而呈指数上升
- 与软件开发和维护的方法不正确有关
- 忽视软件需求分析的重要性
- 轻视软件维护
- 与软件本身特点有关
- 消除软件危机的途径
- 消除“软件就是程序”的错误观念
- 软件开发应是组织良好、管理严密、各类人员协同配合共同完成的项目
- 成熟的软件开发技术和方法
- 软件工具和软件工程支持环境
软件工程
? 软件工程是指导计算机软件开发和维护的一门工程学科。采用工程的概念、原理、技术和方法来开发和维护软件,把经过时间考验而证明正确的管理技术和当前能够得到的最好的技术方法结合起来,以经济地开发出高质量的软件并有效地维护它,这就是软件工程
-
本质特性
-
关注于大型程序的构造
-
中心课题是控制复杂性
将复杂问题分解成可理解的问题,并使各部分之间保持简单的通信关系,此法不能降低复杂性但可使其变为可管理的
-
软件经常变化
需求一直在变化
-
开发软件的效率非常重要
-
和谐地合作是开发软件的关键
-
必须有效的支持它的用户
意味着需要仔细研究用户以确定适当的功能需求、可用性要求等,应写出用户手册和培训材料,注意建立使用新系统的环境(培训用户,使其习惯于新的工作流程)
-
在软件工程领域中通常由具有一种文化背景的人替具有另一种文化背景的人创造产品
软件开发人员通常并不是其他领域专家但需要为其他领域开发软件,就需要事先了解那些领域的流程
-
-
基本原理
-
用分阶段的生命周期计划严格管理
-
坚持进行阶段评审
不能等到编码阶段结束后在进行质量保证工作,理由如下:
- 错误出现往往是由于设计造成的(设计错误占比63%,编码错误占比37%)
- 错误发现与改正得越晚,改正所需付出的代价越高
-
实行严格的产品控制
基准配置管理(基线配置、变动控制):为保持软件各个配置成分的一致性而进行的管理
基线配置:他们是经过阶段评审后的软件配置成分(各个阶段产生的文档或程序代码)
变动控制:一切有关修改软件的建议,特别是涉及对基准配置的修改建议都必须经过审批才可修改 -
采用现代程序设计技术
-
结果应能清楚地审查
根据软件开发项目的总目标及完成期限,规定开发组织的责任和产品标准,从而使所得到的结果能够清楚地审查
-
开发小组的人员应该少而精
-
承认不断改进软件工程实践的必要性
-
-
软件工程方法学
软件工程包括技术和管理两方面的内容
? 管理:通过计划、组织和控制等一系列活动,合理地配置和使用各种资源,以达到既定目标的过程
-
三要素:工具、方法、过程
方法:完成软件开发的各项任务的技术方法,回答“怎样做”的问题
-
传统方法学:也称为生命周期方法学或结构化范型
? 采用结构化技术(结构化分析、设计、实现)
-
面向对象方法学——强调主动地多次反复迭代
面向对象方法:把数据和行为看成同等重要,它是一种以数据为主线,把数据和对数据的操作紧密地结合起来的方法。
? 四个要点:对象、类、继承、消息
-
软件生命周期
三个时期(软件定义、软件开发、软件维护),八个阶段(问题研究、可行性研究、需求分析、概要设计、详细设计、编码和单元测试、综合测试、软件发布运行维护)
- 问题定义:问题是什么
1. 研究出客户所需要解决的问题,确认客户待解决的问题。
2. 结果:写出关于问题性质、工程目标和工程规模的书面 告,并得到客户确认
2. 可行性研究:有可行的解吗
3. 系统分析员压缩和简化系统分析设计,探索这个问题是否值得去解,研究出可行的解决方案
4. 结果:系统的高层逻辑模型;可行性论证 告
5. 需求分析:必须做什么
6. 弄清用户的全部需求,对需求进行分析建模
7. 结果:系统的逻辑模型;用规格说明书准确的记录对目标系统的需求
8. 概要设计:概括地说怎样实现目标系统
9. 完成系统的数据设计、体系结构设计和接口设计;撰写概要设计书
10. 结果:可能的解法(系统流程图、成本效益分析);推荐的系统体系结构(层次图或结构图)
11. 详细设计:怎样具体实现该系统
12. 对概要设计所划分的模块进一步细化;详细描述项目所有内容,并完成详细设计书编制
13. 结果:每个模块的算法和数据结构(程序流程图、PAD图、N-S图、类图等)
14. 编码和单元测试:得到正确、易理解维护的程序模块
15. 综合测试:通过各种类型的测试使软件达到预定的要求
16. 通过各种测试对目标系统进一步测试检验
17. 结果:测试设计及结果
18. 软件发布、运行、维护:使系统持久地满足用户的需要
19. 改正性维护、适应性维护、完善性维护、预防性维护
20. 结果:完整准确地维护记录
- 问题定义:问题是什么
-
软件过程
软件过程是为了获得高质量软件所需要完成的一系列任务的框架,它规定了完成各项任务的工作步骤
需求分析与验证、规格说明与验证、设计与验证、编码与验证、综合测试、维护
-
瀑布模型
按软件开发流程进行顺序开发,适用于目的需求明确的情况
-
特点
-
阶段间具有顺序性和依赖性
- 必须等前一段工作完成后才能开始后一段工作
- 前一段的输出文档就是后一段的输入文档,所以需要保证每个阶段的文档正确才能输出最终正确的结果
-
推迟实现的观点
急于求成而忽略先前的分析会导致总工作量的增加
-
质量保证的观点
文档驱动型,文档作为每个阶段开始和验收的依据
-
-
优点
- 强迫开发人员采用规范的方法
- 严格规定每个阶段必须提交的文档
- 要求每个阶段都需要进行质量保证测试
-
缺点
-
-
文档驱动型脱离实际,只是停留在纸面上,在实践中可能不能满足客户真实需要
-
-
快速原型模型
在用户不能给出完整、准确的需求说明或开发者不能确定算法的有效性、操作系统的适应性或人机交互的形式等多种情况下,可以根据用户的一组基本需求,快速建造一个模型,评估,然后再进一步精化,调整模型,适用于需求不明确的情况
- 迅速
-
增量模型
把软件产品作为一系列的增量构件来设计、编码、集成和测试,每个构件由多个相互作用的模块构成,并且能够完成特定的功能(类似于版本管理,一个个版本更新并最终得到版本)
-
螺旋模型
使用原型及其他方法来尽量降低风险
-
喷泉模型*
典型的面向对象生命周期模型
-
Rational统一过程*
RUP是一种迭代的,以架构为中心的,用例驱动的模型
-
最佳实践
-
迭代式开发
允许软件需求变化
-
管理需求
-
使用基于构件的体系结构
子系统模块
-
可视化建模
画UML图
-
验证软件质量
-
控制软件变更
-
-
-
敏捷过程与极限编程*
-
敏捷软件开发宣言(敏捷价值观)
- 个体和交互胜过过程和工具
- 可以工作的软件胜过面面俱到的文档
弱化文档的重要性,强调客户需求的是一个可以使用的软件
- 客户合作胜过合同谈判
- 响应变化胜过遵循计划
-
极限编程(XP)
-
敏捷过程中最负盛名的一个
-
适用于需求模糊且经常改变的场合
-
适用于有限时间有限开发人员的环境
重构:不改变系统行为的前提下,重新调整和优化系统内部结构,以提高代码的可维护性,降低复杂性,消除冗余
集体所有:每个小组成员都拥有修改代码的权利,每个成员都对全部代码质量负责
持续集成:极限编程主张在一天内多次集成系统,随着需求的更变,应该不断的进行回归测试
现场客户:至少有一名客户代表在项目的整个周期中与开发人员一起紧密地配合工作
系统隐喻:整个系统联系在一起的全局视图,它描述系统如何运作,以及用何种方式把新功能加入到系统中
可持续的开发速度:每周工作不超过40h,连续加班不超过两周
- 极限编程的整体开发过程
- XP适用范围
- 适合规模小、进度紧、需求变化大的软件开发
- 不适用于中大型项目(团队超过十人)、重构会导致大量开销的app
-
-
微软过程
- 微软过程准则
- 微软软件生命周期
- 微软过程模型
-
-
-
小结
- 软件=程序+数据+文档
- 软件危机:原因,现象。办法(软件工程学)
- 软件工程三要素:方法、工具和过程
- 软件生命周期:定义、开发、维护
- 每种模型都有自己适用的软件开发,选择合适的模型进行开发
第二章 软件设计基本概念
设计过程
从工程管理的角度,可以将软件设计分为概要设计阶段和详细设计阶段
- 系统设计阶段:确定系统的具体实现方案
- 设想供选择的方案
- 选取合理的方案
- 推荐最佳方案
- 结构设计阶段:确定软件结构
- 功能分解
- 设计软件结构
- 设计数据库
- 制定测试计划
- 书写文档
- 审查和复审
设计原理*
模块化
把复杂问题分解成许多容易解决的小问题
- 模块:是由边界元素限定的相邻程序元素的序列,而且有一个总体标识符代表它
- 模块化:每一个模块实现一个子功能
- 目的:使一个复杂的大型程序能被人的智力所管理,软件应该具备的唯一属性。
- 每个程序都相应的有一个最适当的模块数目M,使得系统的开发成本最小
- 作用:
- 使软件结构清晰,容易阅读理解
- 使软件容易测试和调试,有助于提高软件可靠性
- 能够提高软件的可修改性
- 有助于软件开发工程的组织管理
- 模块间的信息传递:传送参数数据
- 模块的调用关系和接口:模块间用单向箭头连接,从调用模块指向被调用模块
抽象
现实世界中的一些事物、状态或过程之间总存在着某些相似的方面(共性(。把这些相似的方面集中和概括起来,暂时忽略它们之间的差异
-
一般抽象过程
- 使用层次的方式构造和分析复杂系统
- 对于复杂的动态系统首先可以用一些高级的抽象概念构造和理解,高级概念又可以用一些低级概念构造和理解,如此进行下去直至最低层次的具体元素
-
软件工程抽象过程
- 每一步都是对软件解法的抽象层次的一次精化
- 在可行性研究阶段,软件作为系统的一个完整部件
- 需求分析阶段,软件解法是使用在问题环境内熟悉的方式描述的
- 当由总体设计向详细设计过渡时,抽象的程度也就随之减少了
- 当程序写出来以后,也就达到了抽象的最低层
-
逐步求精
为了能集中精力解决主要问题而尽量推迟对问题细节的考虑。逐步求精是人类解决复杂问题时采用的基本方法,也是许多软件工程技术的基础。
Miller法则:一个人在任何时候都只能把注意力集中在(7±2)个知识块上
- 可以把逐步求精看作是一项把一个是期内必须解决的种种问题按优先级排序的技术。逐步求精方法却把每个问题都将被解决的,而且每个问题都将在合适的时候被解决,但是在任何一个时候一个人都不需要同时处理七个以上的知识块
- 求精实际上是细化过程
- 求精和抽象是两组互补的概念
-
信息隐藏和局部化
-
信息隐藏
一个模块内包含的信息(过程和数据)对于不需要这些信息的模块来说应是不能访问的
-
局部化
把一些关系关系密切的软件元素物理的放的彼此靠近,局部化有利于实现信息隐藏
-
作用
- 隐藏意味着有效的模块化可以通过定义一组独立的模块实现,这些模块彼此间紧紧交换那些为了完成系统功能而必须交换的信息
- 对程序模块修改的时候将最小程度影响到其它模块,易于维护
-
-
模块独立
模块独立的概念是模块化、抽象、信息隐藏和局部化概念的直接结果
-
每个模块完成一个相对独立的特定子功能,并且和其他模块的关系很简单
-
模块独立程度的两个定性标准度量
- 耦合衡量不同模块彼此间互相依赖的紧密程度,耦合要低,即每个模块和其它模块之间的关系要简单
- 内聚衡量一个模块内部各个元素彼此结合的紧密程度。内聚要高,每个模块完成一个相对独立的特定子功能
-
耦合
是对一个软件结构内不同模块之间连接程度的考量。耦合度强弱取决于模块间接口的复杂程度,进入或访问一个模块的点,以及通过接口的数据
-
非直接耦合/完全独立
- 两个模块能独立工作而不需要另一个模块的存在,那么他们完全独立
- 在一个软件系统中不可能所有模块之间都没有任何连接
-
数据耦合:两个模块彼此间通过参数交换信息,而且交换的信息仅仅是数据
-
控制耦合:两个模块彼此间传递的信息中有控制信息
- 控制耦合往往是多余的,在把模块适当分解后通常可以用数据耦合代替它
-
特征耦合:把整个数据结构作为参数传递而被调用的模块只需要使用其中一部分数据元素时,就出现了特征耦合
- 导致对数据的访问失去了控制,从而给计算机犯罪提供了机会
-
公共环境耦合:两个或以上模块通过一个公共数据环境相互作用时,他们之间的耦合称为公共环境耦合
-
公共环境可以是全程变量、共享的通信区、内存的公共覆盖区、任何存储介质上的文件、物理设备等
-
公共环境耦合的复杂程度随耦合的模块个数而变化,当耦合的模块个数增加时复杂程度显著增加。如果只有两个模块有公共环境,那么这种耦合有下面两种可能:
-
一个模块往公共环境送数据,另一个模块从公共环境取数据。这是数据耦合的一种形式,是比较松散的耦合
-
两个模块都既往公共环境送数据又从里面取数据,这种耦合比较紧密,介于数据耦合和控制耦合之间
如果两个模块共享的数据很多,都通过参数传递可能很不方便,这时可以利用公共环境耦合
-
-
-
内容耦合:最高程度的耦合
- 一个模块访问另一个模块的内部数据
- 一个模块不通过正常入口转到另一个模块的内部
- 两个模块有一部分程序代码重叠
- 一个模块有多个出入口
以上情况出现之一,这两个模块就发生了内容耦合
应该坚决避免使用内容耦合
-
-
内聚(重要性高于耦合)
标志着一个模块内各个元素彼此结合的紧密程度,他是信息隐藏和布局化概念的自然扩展,理想的内聚模块只做一件事情
- 偶然内聚:一个模块完成一组任务,这些任务彼此间即使有关系,关系也是很松散的,就叫偶然内聚。
- 偶然内聚出现错误的概率比其他内聚高很多
- 逻辑内聚:一个模块完成的任务在逻辑上属于相同或相似的一类,称为逻辑内聚
- 不同功能的模块混在一起,和用部分程序代码,即使局部功能的修改有时也会影响全局,因此,这部分的代码修改起来也比较困难
- 时间内聚:一个模块包含的任务必须在同一段时间内执行,就叫时间内聚
- 好于逻辑内聚
- 过程内聚:一个模块内的处理元素是相关的,而且必须以特定的次序进行
- 通信内聚:模块中所有元素都使用同一个输入数据和(或)产生同一个输出数据,则为通信内聚
- 顺序内聚:一个模块内的处理元素和同一个功能密切相关,而且这些处理必须顺序执行
- 功能内聚:模块中所有处理元素属于一个整体,完成一个单一的功能,则为功能内聚。(最高程度的内聚)
- 偶然内聚:一个模块完成一组任务,这些任务彼此间即使有关系,关系也是很松散的,就叫偶然内聚。
-
-
启发规则
- 改进软件结构提高模块独立性
- 通过模块分解或合并,降低耦合提高内聚
- 模块规模应当适中
- 过大的模块往往是由于分解不充分
- 过小的模块开销大于有效操作,会使系统接口变得复杂
- 深度、宽度、扇入扇出都应当适当
- 深度表示软件结构中控制的层数,粗略地标志一个系统的大小和复杂程度
- 宽度是软件结构内同一层次上的模块总数的最大值,一般来说,宽度越大系统越复杂。对宽度影响最大的因素是模块的扇出
- 扇出是一个模块直接控制或调用的模块数目
- 设计的好的软件结构通常顶层扇出比较高,中层扇出较少,底层扇入到公共的实用模块中去
- 模块的作用域应该在控制域之内
- 模块的作用域:受到该模块内一个判定影响的所有模块的集合
- 模块的控制域:是这个模块本身以及所有直接或间接从属于它的模块的集合
- 力争降低模块接口的复杂度
- 设计单入口单出口的模块
- 模块功能应该可以预测:只要输入的数据相同就产生相同的输出
- 改进软件结构提高模块独立性
-
小结
- 总体设计阶段的基本目的:用比较抽象概括的方式确定系统如何完成任务
第三章 详细设计
详细设计阶段的根本目标:确定应该怎样具体的实现所要求的系统。经过这个阶段的设计工作,应该得出对目标系统的精准描述,从而在编码阶段可以把这个描述直接翻译成用某种程序设计语言的代码
结构程序设计
- 经典定义:如果一个程序的代码块仅仅通过顺序选择和循环这三种基本控制结构进行连接,并且每个代码块只有一个入口和出口,则称这个程序是结构化的
- 更全面定义:结构程序设计是尽可能少用GOTO语句的程序设计方法。最好仅在检测出错误时才使用GOTO语句,且应该总是使用向前的GOTO语句
- 三条黄金规则
- 置用户于控制之下
- 减少用户记忆负担
- 保持界面一致
人机界面设计
-
设计问题
-
系统响应时间
- 指从用户完成某个控制动作,到软件给出预期的响应之间的这段时间
- 不能过长(用户会感到紧张和沮丧),也不能太短(迫使用户加快操作节奏,可能会犯错)
-
用户帮助设施
-
大多数现代软件都提供练级帮助设施,这使得用户无需离开用户界面就能解决自己的问题
-
集成的帮助设施
设计在软件里面,对用户操作敏感,用户可从与刚刚完成的操作有关的主体中选择一个请求帮助
-
附加的帮助设施
在系统建成后再添加到软件中的,它实际上是一种查询能力有限的联机用户手册
-
集成的优于附加的帮助设施
-
-
出错信息处理
- 出错信息和警告信息,是出现问题是交互式系统给出的坏消息
-
命令交互
- 多数情况下,用户既可以用菜单也可以用键盘命令进行软件交互
-
-
设计过程
是一个迭代的过程,通常先创建设计模型,再用原型实现这个设计模型,并由用户试用和评估,根据用户意见进行修改
-
人机界面设计指南
-
界面分类
- 菜单型
- 对话框型
-
一般交互界面
-
一般交互指南涉及信息显示,数据输入和系统整体控制
保持一致性。
使用一致的格式提供有意义的反馈(视觉、听觉)
在执行有较大破坏性的动作之前要求用户确认。
允许取消绝大多数操作减少两次操作之间必须记忆的信息量
提高对话、移动和思考的效率
允许犯错误
按功能对动作分类,并据此设计屏幕布局提供对用户工作敏感的帮助设施
用简单动词或动词短语作为命令名
-
-
信息显示界面
-
数据输入界面
-
过程设计工具
程序流程图
又称为程序框图,历史悠久使用最为广泛的描述过程设计的方法,但也是最混乱的一种方法
- 缺点
- 本质上不是逐步求精的好工具
- 用箭头代表控制流,因此程序猿可以不受约束不顾结构程序设计的精神,随意转移控制
- 程序流程图不易表示数据结构
盒图(N-S图)
一种不允许违背结构程序设计精神的图形工具
- 特点
- 功能域明确
- 不可能任意转移控制
- 很容易确定局部和全程数据的作用域
- 很容易表现嵌套关系,也可以表示模块的层次结构
PAD图
- 优点
- 使用表示结构化控制结构的PAD符 所设计出来的程序必然是结构化程序
- PAD图所秒回的程序结构十分清晰。途中最左边的竖线是程序的主线,即第一层结构
- 用PAD图表现程序逻辑,易读、易懂、易记
- 容易将PAD图转换成高级语言源程序,这种转换可用软件工具自动完成
- 即可用于表示程序逻辑,也可用于描绘数据结构
- PAD图的符 支持自顶向下、逐步求精方法的使用。
判定表
包含多重嵌套的条件选择,用判定表能够清晰地表示复杂的条件组合与应做的动作之间的相应关系
判定表需要考虑到所有可能出现的组合,不然就容易隐藏bug
判定树
过程设计语言(PDL)
也称伪码
优点:
- 已经有自动处理PDL的程序存在,而且可以自动由PDL生成程序代码
缺点:
? 不如图形工具形象直观,描述复杂的条件组合与动作间的对应关系时不如判定表清晰简单
面向数据结构的设计方法
Jackson图
-
顺序结构
-
选择结构
在顺序结构的标记右上角有一个°标记
-
重复结构
在顺序结构的标记右上角有一个*标记
改进的Jackson图
Jackson图的缺点是,这种工具表示选择或重复结构时,选择条件或者循环结束条件不能直接在图上表示出来,影响了图的表达能力,并且连线为斜线,在行式打印机上不易输出
Jackson方法
五个步骤:
-
分析并确定输入数据和输出数据的逻辑结构,并用Jackson图庙会这些数据结构
-
找出输入数据结构和输出数据结构中有对应关系的数据单元
对应关系:指有直接的因果关系,在程序中可以同时处理的数据单元。但对于重复出现的数据单元,重复的次序和次数必须都相同才有可能有对应关系
-
导出描绘程序结构的Jackson图,此图应该综合输入数据结构和输出数据结构的层次关系而导出来
-
列出所有操作和条件(包括分支条件和循环结束条件),并且把它们分配到程序结构图的适当位置
-
用伪代码表示程序
程序复杂度的定量度量
McCabe方法
- 流图:为了突出表示程序的控制流,实际上是退化了的程序流程图,仅仅描绘程序的控制流程
- 任何方法表示的过程设计结果,都可以翻译成流图
- 在过程设计中包含复合条件时,应把复合条件分解为若干个简单条件,每个简单条件对应流图中的一个节点
- 计算环形复杂度的方法
- 环形复杂度定量度量程序的逻辑复杂度
- 计算方法
- 流图中线性无关的区域数等于环形复杂度
- 环形复杂度V(G)=E-N+2,其中E为流图中边的条数,N是节点数
- V(G)=P+1,其中P是流图中判定结点的数目
- 环形复杂度的用途
- 是一种对测试难度的一种定量度量,也能对软件最终的可靠性给出某种预测
- 环形复杂度越高,程序往往越困难、越容易出问题,V(G)≤10为宜
Halstead方法
根据程序中运算符和操作数的总数来度量程序的复杂程度
N=N1+N2,N1为程序中运算符出现的总次数,N2为操作数出现的总次数,N为程序长度
-
预测程序长度的公式
H = n 1 l o g 2 n 1 + n 2 l o g 2 n 2 H=n_1log_2n_1+n_2log_2n_2 H=n1?log2?n1?+n2?log2?n2? -
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!