这门纯理论的课是真的无聊,居然还要闭卷考……记个笔记方便背……
一、软件工程与软件过程
1.1 计算机软件
计算机软件的定义:计算机软件指计算机系统中与计算机硬件相互依存的另一部分,包括程序、数据及相关文档。
程序是按事先设计的功能和性能要求执行的指令序列。
数据是使程序能正常操纵信息的数据结构。
文档是与程序开发、维护和使用有关的图文材料。
软件发展阶段:程序设计阶段(1950-1960),程序系统阶段( 1960-1970),软件工程阶段(1970-)。
软件危机:1、如何开发软件满足日益增长的需求;2、如何有效维护软件。
软件工程的出现原因:软件危机,“摆脱软件危机的出路在于软件开发的标准化和工程化”。
软件的特点:逻辑实体,开发成本和进度难以估算;维护工作量大;使用运行不会磨损老化;对计算机系统有依赖;只能手工开发;软件本身复杂;开发成本昂贵;相当多的软件工作设计到社会因素。
软件的分类:
按软件的功能划分:
- 系统软件
- 操作系统
- 编译程序
- ……
- 支撑软件
- 数据库管理系统
- 网络软件
- 软件工具
- 软件开发环境
- 应用软件
- 商业数据处理软件
- 工程与科学计算软件
- 计算机辅助设计/制造软件
- 智能产品嵌入软件
- 事务管理、办公自动化软件
- 计算机辅助教学软件
按……划分……
软件语言:用于书写计算机软件的语言。主要包括:
- 需求定义语言
- 功能性语言
- 设计性语言
- 实现性语言
- 文档语言
1.2软件工程
定义:略。
软件工程框架:
- 目标
- 可用性
- 正确性
- 合算性
- 原则
- 选取事宜的开发模型
- 采用合适的设计方法
- 提供高质量的工程支持
- 重视软件工程的管理
- 过程
- 基本过程
- 支持过程
- 组织过程
软件过程三要素:过程、方法、工具。
过程是软件产品加工所经历的一系列有组织的活动,保证能够合理、高质量和及时地开发出软件。
方法为软件开发提供“如何做”的技术。
工具可为过程和方法提供自动或半自动的支持。
软件生命周期:
- 软件定义
- 问题定义
- 可行性研究
- 需求分析
- 软件开发
- 概要设计
- 详细设计
- 编码和单元测试
- 综合测试
- 运行维护
1.3软件过程
软件过程是生产一个最终满足需求并且达到工程目标的软件产品所需的步骤。
软件生存周期过程:基本过程、支持过程、组织过程。
能力成熟度模型:改进软件过程的一种策略。 结构:1、成熟度等级;2、过程能力;3、关键过程域;4、目标;5、公共特性;6、关键实践。
能力成熟度等级:1、初始级;2、可重复级;3、已定义级;4、已管理级;5、优化级。
关键过程域:决定过程能力的关键过程。
1.4软件过程模型
软件过程模型是软件开发全部过程、活动和任务的结构框架。典型的有瀑布模型、演化模型、喷泉模型、基于构件的开发模型和形式化方法模型等。
1.5 Rational统一开发过程RUP
最佳软件开发实践:1、迭代式软件开发;2、需求管理;3、基于构件的软件体系结构;4、建立软件可视化模型;5、不断验证软件质量;6、控制变更。
软件开发过程的作用:1、成为开发组活动顺序的向导。2、详细说明要开发哪些制品,何时开发。3、指导每一个成员及整个开发组的工作。4、提供监控和度量项目产品和活动所依据的准则。
Rational统一开发过程(RUP, Rational Unify Process)描述了如何在软件开发组织中严格分配任务和职责的方法。
过程的静态描述:过程模型。
主要模型元素:
- 工作人员:完成工作的角色
- 活动:工作人员所执行的工作
- 思考步骤
- 执行步骤
- 评审步骤
- 制品:过程生产、修改或使用的一些信息
- 管理集
- 需求集
- 设计集
- 实现集
- 实施集
- 工作流:用来描述生成结果的活动序列
- 核心工程工作流
- 业务建模工作流
- 需求工作流
- 分析和设计工作流
- 实现工作流
- 测试工作流
- 实施工作流
- 核心支持工作流
- 项目管理工作流
- 配置和变更管理工作流
- 环境工作流
- 核心工程工作流
过程的动态描述:迭代开发。在 RUP 中,迭代过程分为几个阶段:
- 初始阶段
- 细化阶段
- 构造阶段
- 移交阶段
Rational统一过程的特点:用例驱动的、以体系结构(架构)为中心的、迭代和增量的过程。用例建模技术可以用为大多数项目相关人员理解的形式来表述问题。
二、结构化分析
2.1概述
需求分析是发现、求精、建模、规格说明和复审的过程。
结构化分析方法:主要思想:抽象与自顶向下的逐层分解(控制复杂性的两个基本手段)。
抽象:在每个抽象层次上忽略问题的内部复杂性,只关注整个问题与外界的联系
分解:将问题不断分解为较小的问题,直到每个最底层的问题都足够简单为止
2.2与用户沟通的方法
访谈(或称为会谈)是最早开始运用的获取用户需求的技术,也是迄今为止仍然广泛使用的主要的需求分析技术。
访谈的两种基本形式:正式的访谈和非正式的访谈。
简易的应用规格说明技术:一种面向团队的需求收集法,这种方法提倡用户与开发者密切合作,共同标识问题,提出解决方案的要素,商讨不同的方法并指定基本的需求。
软件原型:快速建立软件原型是最准确、最有效、最强大的需求分析技术。快速原型就是快速建立起来的旨在演示目标系统主要功能的程序。
2.3分析建模的目标
- 描述用户的需求。
- 为软件设计工作奠定基础。
- 定义一组需求,一旦开发出软件产品之后,就可以用这组需求为标准来验收。
- 为了达到上述这些目标,在结构化分析过程中导出的分析模型的形式。
分析建模的结构: ||数据字典|| |----|----|----| |数据流图|状态转换图|实体——关系图| |处理规格说明|控制规格说明|数据对象描述|
数据字典是模型的核心,它包含了软件使用和产生所有数据的描述。
数据流图:用于功能建模,描述系统的输入数据流如何经过一系列的加工变换逐步变换成系统的输出数据流。
状态转换图:用于行为建模,描述系统接收哪些外部事件,以及在外部事件的作用下的状态迁移情况。
实体—关系图:用于数据建模,描述数据字典中数据之间的关系。
数据对象是对软件必须理解的复合信息的表示。
属性定义了数据对象的性质。
关系:数据对象彼此之间相互连接的方式称为关系,也称为联系。
2.4实体—关系图的符号
基本成分:实体(即数据对象)、关系和属性。
实体——矩形框。
关系——连接相关实体的菱形框。
属性——椭圆形或圆角矩形。
用无向边把实体(或关系)与其属性连接起来。
2.5数据流图
数据流图的基本元素:数据流、加工、文件、源或宿。
数据流:每个数据流用由一组固定成分的数据组成并拥有一个定义明确的名字标识。
数据流组成:数据流组成是数据流条目的核心,它列出组成该数据流的各数据项。
源或宿:存在于软件系统之外的人员或组织,表示软件系统输入数据的来源和输出数据的去向,因此也称为源点和终点。
数据流图的扩充符号: |星号|加号|异或| |----|----|----| |*|+|⊕| |与|或|异或|
2.6状态转换图
简称状态图,通过描绘系统的状态及引起系统状态转换的事件,来表示系统的行为。
状态是任何可以被观察到的系统行为模式,一个状态代表系统的一种行为模式。状态规定了系统对事件的响应方式。
状态图中定义的状态主要有:初态(即初始状态)、终态(即最终状态)和中间状态。在一张状态图中只能有一个初态,而终态则可以有0至多个。
事件:简而言之,事件就是引起系统做动作或(和)转换状态的控制信息。
状态图中的符号: |初态|终态|中间状态| |---|---|---| |实心圆|同心圆(内圆实心)|圆角矩形|
2.7数据字典
数据字典包含的信息:名字、别名、使用地点与方式、内容描述、补充信息。
字典条目:不同的开发组织或团队可以根据项目的需要定义字典条目的描述内容。
三、结构化设计
结构化设计是将结构化分析得到的数据流图映射成软件体系结构的一种设计方法。
设计准则:模块化、自顶向下逐步求精、信息隐蔽、高内聚低耦合等。
分为概要设计和详细设计两大步骤。
3.1结构化设计与结构化分析的关系
结构化分析的结果为结构化设计提供了最基本的输入信息。
3.2 软件设计的概念和原理
模块是由边界元素限定的相邻的程序元素(如数据说明,可执行的语句)的序列,而且有一个总体标识符来代表它。模块是指具有一定功能的可以用模块名调用的一组程序语句,如函数、子程序等。
模块化就是把程序划分成可独立命名且独立访问的模块,每个模块完成一个子功能,把这些模块集成起来构成一个整体,可以完成指定的功能满足用户的需求
调用(call):用从一个模块指向另一个模块的箭头来表示,其含义是前者调用了后者。
数据(data):模块调用时需传递的参数可通过在调用箭头旁附加一个小箭头和数据名来表示。
深度:程序结构图中控制的层数。
宽度:程序结构图中同一层次上模块总数的最大值。
扇出(fan out):该模块直接调用的模块数目。
扇入(fan in):能直接调用该模块的模块数目。
深度和宽度在一定程度上反映了程序的规模和复杂程度。
一个模块的扇出过大通常意味着该模块比较复杂,然而扇出太少,可能导致深度的增加。一般情况,一个模块的扇出以3~9为宜。
个模块的扇入表示有多少模块可直接调用它,它反映了该模块的复用(reuse)程度,因此模块的扇入越大越好。
每个程序都相应地有一个最适当的模块数目M,使得系统的开发成本最小。
模块化定义的5条标准:模块可分解性、模块可组装性、模块可理解性、模块连续性、模块保护性。
抽象:把事物的相似方面集中和概括起来,暂时忽略它们之间的差异。
处理复杂系统的唯一有效的方法是用层次的方式构造和分析它。
逐步求精:为了能集中精力解决主要问题而尽量推迟对问题细节的考虑。
信息隐藏原理指出:应该这样设计和确定模块,使得一个模块内包含的信息(过程和数据)对于不需要这些信息的模块来说,是不能访问的。实际上,应该隐藏的不是有关模块的一切信息,而是模块的实现细节。
3.3模块独立
耦合(Coupling)是对一个软件结构内不同模块之间互连程度的度量。
数据耦合:两个模块彼此间通过参数交换信息,而且交换的信息仅仅是数据。
控制耦合:传递的信息中有控制信息(尽管有时这种控制信息以数据的形式出现)。
内聚:标志一个模块内各个元素彼此结合的紧密程度。
模块内的高内聚往往意味着模块间的松耦合。
偶然内聚:如果一个模块完成一组任务,这些任务彼此间即使有关系,关系也是很松散的。
逻辑内聚:一个模块完成的任务在逻辑上属于相同或相似的一类(如一个模块产生各种类型的全部输出)。
时间内聚:一个模块包含的任务必须在同一段时间内执行(如模块完成各种初始化工作)。
过程内聚:一个模块内的处理元素是相关的,而且必须以特定次序执行。
通信内聚:模块中所有元素都使用同一个输入数据和(或)产生同一个输出数据。
顺序内聚:一个模块内的处理元素和同一个功能密切相关,而且这些处理必须顺序执行(通常一个处理元素的输出数据作为下一个处理元素的输入数据)。
功能内聚:模块内所有处理元素属于一个整体,完成一个单一的功能。功能内聚是最高程度的内聚。
内聚类型 | 优劣评分 |
---|---|
功能内聚 | 10分 |
顺序内聚 | 9分 |
通信内聚 | 7分 |
过程内聚 | 5分 |
时间内聚 | 3分 |
逻辑内聚 | 1分 |
偶然内聚 | 0分 |
3.4启发规则
常用的启发规则:
- 改进软件结构提高模块独立性
- 模块规模应该适中
- 模块规模应该适中
- 模块的作用域应该在控制域之内
- 力争降低模块接口的复杂程度
- 设计单入口单出口的模块
- 模块功能应该可以预测
3.5表示软件结构的图形工具
结构化设计的步骤:
- 建立初始结构图
- 对结构图进行改进
- 书写设计文档
- 设计评审
3.6面向数据流的设计方法
结构化设计是将结构化分析的结果(数据流图)映射成软件的体系结构(结构图)。
信息流:变换流和事务流。
将数据流图分为变换型数据流图和事务型数据流图,对应的映射分别称为变换分析和事务分析。
变换流:特征:数据流图可明显地分成输入、变换、输出三部分。
事务分析:事务分析的设计步骤和变换分析的设计步骤大部分相同或类似,主要差别仅在于由数据流图到软件结构的映射方法不同。
由事务流映射成的软件结构包括一个接收分支和一个发送分支。
构件:对于一个大系统,常常把变换分析和事务分析应用到同一个数据流图的不同部分,由此得到的子结构形成“构件”,可以利用它们构造出完整的软件结构。
如果数据流不具有显著的事务特点,最好使用变换分析;反之,如果具有明显的事务中心,则应该采用事务分析技术。
事务流:特征:数据流沿着输入路径到达一个事务中心,事务中心根据输入数据的类型在若干条动作路径中选择一条来执行。
事务中心的任务:接收输入数据(即事务);分析每个事务的类型;根据事务类型选择执行一条动作路径。
数据流图映射到结构图的步骤:
- 数据流图映射到结构图的步骤
- 确定数据流图的类型(变换型、事务型)
- 将DFD映射成初始结构图:采用变换分析或事务分析技术,将DFD映射成初始结构图
- 改进初始结构图
变换分析的任务是将变换型的DFD映射成初始的结构图。
3.7人—机界面设计
人—机界面设计问题:
- 系统响应时间
- 用户帮助设施
- 出错信息处理
- 命令交互
界面设计指南:
- 一般交互
- 信息显示
- 数据输入
3.8过程设计
只用“顺序”、“选择”和“循环”这3种基本的控制结构就能实现任何单入口单出口的程序
结构化:如果一个程序的代码块仅仅通过顺序、选择和循环这3种控制结构进行连接,并且每个代码块只有一个入口和一个出口,则称这个程序是结构化的。(少用goto)
3.9过程设计工具
指描述程序处理过程的工具,可以分为图形表格和语言三类。
主要有:
- 程序流程图(程序框图)
- 盒图(N-S图)
- 问题分析图(PAD图)
- 判定表
- 判定树
过程设计语言(PDL、伪代码)
3.10面向数据结构的设计方法
最终目标是得出对程序处理过程的描述。
Jackson图:主要有:顺序结构、选择结构、重复结构。
四、结构化实现
4.1编码
通常把编码和测试统称为实现。
编码就是把软件设计翻译成计算机可以理解的形式—用某种程序设计语言书写的程序。
软件测试仍然是保证软件质量的关键步骤,它是对软件规格说明、设计和编码的最后复审。
需要注意的:
- 编程风格与编码标准
- 源程序文档化
- 数据说明规范化
- 程序代码结构化
- 输入和输出可视化
编程语言的分类:
按照语言的抽象级别:低级语言和高级语言。
按照应用的范围:通用语言和专用语言。
按照用户的要求:过程性语言和非过程性语言。
按照语言所包含成分的性质:过程性语言、面向对象语言、面向英特网语言等。
4.2软件测试基础
黑盒测试:已经知道了产品应该具有的功能,可以通过测试来检验是否每个功能都能正常使用。
白盒测试:知道产品内部工作过程,可以通过测试来检验产品内部动作是否按照规格说明书的规定正常进行。
流图(程序图):描绘程序的控制流程。
4.3逻辑覆盖
逻辑覆盖是设计白盒测试方案的一种技术。
逻辑覆盖方式主要有:
- 语句覆盖
- 判定覆盖
- 条件覆盖
- 判定/条件覆盖
- 条件组合覆盖
4.4控制结构技术
基本路径测试步骤如下:
- 根据过程设计结果画出相应的流图
- 计算流图的环形复杂度
- 确定线性独立路径的基本集合
- 设计可强制执行基本集合中每条路径的测试用例
条件测试:用条件测试技术设计出的测试用例,能够检查程序模块中包含的逻辑条件。
数据流测试方法是根据程序中变量定义和使用的位置,选择程序的测试路径。
由于程序内的语句因变量的定义和使用而彼此相关,因此,数据流测试方法能有效地发现错误。但是,在度量测试覆盖率和选择测试路径时,数据流测试比条件测试更困难。
循环测试是一种白盒测试技术,它专注于测试循环结构的有效性。在结构化的程序中通常只有3种循环,分别是简单循环、嵌套循环和串接循环。
4.5黑盒测试技术
黑盒测试着重测试软件的功能需求,也就是说,黑盒测试让软件工程师设计出能充分检查程序所有功能需求的输入条件集。
白盒测试在测试过程的早期阶段进行,而黑盒测试主要用于测试过程的后期。
等价划分是一种黑盒测试方法,这种方法把程序的输入域划分成数据类,据此可以导出测试用例。
根据等价类设计测试方案:1、设计一个测试方案,尽可能多地覆盖未被覆盖的有效等价类,重复。2、设计一个测试方案,只覆盖一个未被覆盖的无效等价类,重复。
边界值分析:使用边界值分析方法设计测试方案首先应该确定边界情况,这需要经验和创造性。
错误推断:错误推测法在很大程度上靠直觉和经验进行。
4.6测试策略
测试步骤:
- 单元测试:着重测试每个单独的模块,以确保它作为一个单元来说功能是正确的。
- 代码审查
- 测试软件
- 集成测试:把模块装配(即集成)在一起形成完整的软件包,在装配的同时进行测试。
- 非渐增式测试
- 渐增式测试
- 自顶向下集成
- 自底向上集成
- 回归测试
- 确认测试(验收测试):测试在需求分析阶段确定下来的确认标准,验证软件的有效性。
- Alpha测试:在受控的环境中进行。
- Beta测试:测试软件在开发者不能控制的环境中的“真实”应用。
- 调试(纠错):调试是在测试发现错误之后排除错误的过程。
- 超出软件工程范畴的测试
4.7调试
调试是软件开发过程中最艰巨的脑力劳动。
调试的途径:
- 蛮干法
- 回溯法
- 原因排除法
- 二分查找法
- 归纳法
- 演绎法
4.8软件可靠性
软件可靠性:程序在给定的时间间隔内,按照规格说明书的规定成功地运行的概率。
软件的可用性:程序在给定的时间点,按照规格说明书的规定,成功地运行的概率。
系统平均无故障时间(MTTF)
和平均维修时间(MTTR)
符号:
符号 | 含义 |
---|---|
\(E_T\) | 测试之前程序中错误总数 |
\(I_T\) | 程序长度(机器指令总数) |
\(\tau\) | 测试(包括调试)时间 |
\(E_d(\tau)\) | 在0~\(\tau\)期间发现的错误数 |
\(E_c(\tau)\) | 在0~\(\tau\)期间改正的错误数 |
基本假定:
1、在类似的程序中,单位长度里的错误数\(E_t\)/\(I_T\)近似为常数。
2、失效率正比于软件中剩余的(潜藏的)错误数,而MTTF与剩余的错误数成反比。
估算平均无故障时间
经验表明,平均无故障时间与单位长度程序中剩余的错误数成反比。
估计错误总数的方法
1、植入错误法。 2、分别测试法(随机把一部分错误加上标记)。