# 概述
# 软件和软件危机
软件的定义、特点及定义
软件的定义
- 软件不是程序,而是程序、数据以及开发、使用和维护程序需要的所有文档的完整集合。
软件的特点
- 软件是一种逻辑产品,而不是具体的物理实体,具有抽象性。
- 软件产品的生产主要是开发研制,没有明显的制造过程。
- 软件产品在使用过程中,不存在磨损、消耗老化等问题。
- 软件产品的开发主要是脑力劳动,还未完全摆脱手工开发方式,大部分产品是 “定做的”,生产效率低。
- 软件产品的成本相当昂贵,软件费用不断增加,软件的研制需要投入大量的人力、物力和资金,生产过程中还需对产品进行质量控制,对每件产品进行严格的检验。
- 软件对硬件和环境有不同程度的依赖性,为了减少这种依赖性,在软件开发中提出了软件的可移植性问题
- 软件是复杂的。
软件的分类
- 服务类软件
- 此类软件是面向用户的,为用户提供各种服务,包括多种软件开发工具和常用的库函数及多种语言的集成化软件
- 维护类软件
- 此类软件是面向计算机维护的,包括错误诊断和检测软件、测试软件、多种调试所用软件。
- 操作管理软件
- 此类软件是面向计算机操作系统和管理的,包括各种操作系统、网络通信系统、计算机管理软件
- 服务类软件
软件危机的定义及表现形式
软件危机
- “软件危机” 是指在计算机软件的开发和维护过程中所遇到的一系列严重问题,软件危机主要包含了两个方面的问题:
- 如何开发软件以满足软件日益增长的需求
- 如何维护数量不断增长的已有软件
- “软件危机” 是指在计算机软件的开发和维护过程中所遇到的一系列严重问题,软件危机主要包含了两个方面的问题:
软件危机表现形式
- 软件开发成本和研制进度的估计常常很不精确。
- 经费预算经常突破,完成时间一拖再拖
- 有时为了赶进度和节约成本所采取的一些权宜之计又往往影响了软件产品的质量
- “已完成” 的软件不能满足用户要求。
- 软件开发人员常常对用户需求只有模糊的了解,甚至对所要解决的问题还没有确切认识的情况下,就匆忙着手编写程序了。
- 软件产品质量差,可靠性得不到保证。
- 软件产品可维护性差,软件开发人员在开发过程中按各自的风格工作,各行其是,没有统一、公认的规范和完整规范的文档
- 软件成本在计算机系统总成本中所占的比例逐年上升。
- 软件开发生产率提高的速度远远跟不上计算机应用速度普及深入的趋势。
- 软件开发成本和研制进度的估计常常很不精确。
软件危机的产生原因及解决途径
产生软件危机的原因
- 软件是计算机的逻辑部件
- 软件开发的管理困难
- 软件开发费用不断增加,维护费用急剧上升
- 软件开发技术落后。
- 生产方式落后。
- 开发工具落后,生产效率提高缓慢
解决软件危机途径
- 首先应该对计算机软件有一个正确的认识,彻底清除 "软件就是程序" 的错误观念。
- 要使用好的开发技术和方法,并且要不断研究探索更好更有效的技术和方法。
- 要有良好的组织、严密的管理,各类人员要相互配合,共同完成任务。(软件开发不是某种个体劳动的神秘技巧)
- 应该开发和使用好的软件工具。
- 软件系统开发与制造一台机器或建造一栋大厦有许多相同之处,所以要采用 “工程化” 的思想做指导来解决软件研究中面临的困难和混乱,从而走出软件危机的困境。
# 软件工程
软件工程的定义及目标
软件工程的研究内容和基本原理
软件工程的发展史
# 软件过程和软件的生存周期
软件过程
软件生存周期
# 软件开发模型
瀑布模型
快速原型模型
增量模型
螺旋模型
喷泉模型
基于构建的开发模型
统一过程(RUP)模型
基于形式化的开发模型
# 传统的软件工程和面向对象的软件工程
传统的软件工程方法
面向对象的软件工程方法
传统的软件工程和面向对象的软件工程的分析方法对比
# 本章小结
- 软件工程自 1968 年提出至今,正式发展成为用于指导软件生产工程化,覆盖软件开发方法学、软件工具和环境、软件工程管理学等内容的一门课程。
- 本章节主要介绍了软件工程的基本内容,包括软件工程的学科背景、软件生存周期理论、软件开发模型、软件工程方法论等
# 可行性研究
可行性研究的目的和任务
目的:用最小的代价在尽可能短的时间内确定问题是否能够解决。
主要任务:
- 进行概要的分析研究
- 初步确定项目的规模和目标
- 确定项目的约束和限制
- 分析几种可能解法的利弊
四个方面研究各种解法的可行性
- 经济可行性
- 技术可行性
- 操作可行性
- 法律可行性
可行性研究的步骤
- 复查并确定系统规模和目标
- 研究目前正在使用的系统
- 建立新系统的高层逻辑模型
- 导出和评价各种方案
- 推荐可行方案
- 草拟初步的开发计划
- 编写可行性研究报告提交审查
系统流程图
- 系统流程图符号
常用 5 种基本符号
![常用系统流程图]()
11 种系统符号
![11种系统符号]()
成本 - 效益分析
货币的时间价值
- 成本估算的目的是对项目投资。经过成本估算后,得到项目开发时需要的费用,该费用就是项目的投资
- 项目完成后,应取得相应的效益。有多少效益才划算?这就是应该考虑货币的时间价值。因为投资是现在进行的,而效益是将来获得的。
投资回收期
- 通常用投资回收期衡量一个开发项目的价值。所谓投资回收期就是使累计的经济效益等于最初的投资费用所需要的时间
- 总的来说就是,投资回收期越短,就可以越快获得利润,该项目就越值得投资开发。
纯收入
- 整个生存周期之内系统的累计经济效益与投资之差
- 这相当于投资一个软件系统和把钱存入银行中 (或做其他项目)两种方案的优劣比较。
- 如一个项目纯收入为零,而开发一个系统还要冒风险,则不值得投资开发
可行性研究报告的主要内容
- 可行性研究结束后要提交的文档是可行性研究报告,尽管可行性研究报告的格式各有不同,但主要内容应该包括以下几项
- 引言
- 可行性研究前提
- 对现有系统的分析
- 对所建设系统的分析
- 经济可行性
- 技术可行性
- 社会因素的可行性
- 其他与设计有关选择方案
- 其他与设计有关的专门问题
- 结论意见
# 本章小结
可行性研究阶段是进一步探讨问题定义阶段所确定的问题是否有可行性的解。尤其对于大型项目的开发,可行性研究是必需的。主要通过经济可行性、技术可行性、法律可行性、操作可行性这四个方面来探讨,是否能够解决以及是否值得去解决。通过可行性研究可以减少技术风险和投资风险。
系统流程图用来表达分析员对现有系统的认识和描绘他对未来物理系统的设想
成本 - 效益分析是可行性研究的一项主要内容,它主要是从经济角度判断该项目是否继续下去的依据。
# 软件需求分析
需求分析的任务和步骤
需求分析的任务
- 确定对系统的综合需求
- 功能需求
- 性能需求
- 环境需求
- 接口要求
- 用户界面需求
- 分析系统的数据需求
- 建立软件的逻辑模型
- 编写软件需求规格说明书 (Software Requirement Specification SRS)
- 需求分析评审
- 确定对系统的综合需求
需求分析的步骤 (四个步骤)
- 需求获取:调查研究
- 需求提炼:分析建模
- 需求描述:编写 SRS(需求规格说明书)
- 需求验证:需求不清,不一致,二义性等问题
需求获取的常用方法
- 客户访谈
- 建立联合分析小组
- 问题分析与确认
快速建立软件原型来获取需求
快速原型 特点
- 快速
- 容易修改
判断是否选择原型法来帮助获取需求
- 需求已经建立,并且可以预见是相当稳定吗?
- 软件开发人员和用户已经理解了目标系统的应用领域吗?
- 问题是否可被模型化?
- 用户能否清楚地确定基本的系统需求?
- 有任何需求是含糊的吗?
- 已知的需求中存在矛盾吗?
快速建立软件原型来获取需求
功能分解方法
结构化分析方法
信息建模方法
面向对象方法
结构化分析方法
自顶向下逐层分解的分析策略
结构化分析描述工具
数据流图
数据字典
- 数据字典的内容及使用符号
- 数据字典的实现
加工逻辑的描述
- 结构化语言
- 判定表
- 判定树
需求分析图形工具
层次方框图
维纳图
- 用 大括号 [{].{.label} 区分信息的层次
IPO 图 (Input - Process - Output)
SA (Structured Analysis 结构化分析) 方法应用
- 项目说明
- 数据流图
- 数据字典
数据库内容的需求分析和描述
数据库内容的需求分析
- 信息需求
- 处理需求
- 使用需求
- 建立各局部应用的 E-R 模型
- 建立全局 E-R 模型
数据库内容的需求分析描述
实体联系 (E-R)
- 实体型
- 属性和联系
联系
- 一对一联系
- 一对多联系
- 多对多联系
需求规格说明书
- 需求规格说明书主要内容
- 引言
- 编写目的
- 项目背景
- 定义
- 参考资料
- 任务概述
- 目标
- 运行环境
- 条件和约束
- 数据描述
- 静态数据
- 动态数据:(输入、输出数据)
- 数据库描述
- 数据字典
- 数据采集
- 功能需求
- 功能划分
- 功能描述
- 性能需求
- 数据精确度
- 时间特性
- 适应性
- 运行需求
- 用户界面
- 硬件接口
- 软件接口
- 故障处理
- 其他需求
- 包括可使用性、安全保密性、可维护性、可移植性等
- 引言
# 本章小结
软件分析是软件生存周期一个十分重要的阶段,其根本任务是确定用户对软件系统的需求。他是项目开发的基础,他要确定软件系统做什么,具有什么功能、性能,有什么约束条件等。把这些问题搞清楚之后,要用某种无二义性的描述形成需求规格说明书。
需求分析的结构是软件开发的重要基础,必须经过严格评审并得到用户确认。要从一致性、完整性、现实性和有效性四个方面复审软件需求规格说明书
# 软件总体设计
# 软件总体设计的目标和任务
- 总体设计阶段的基本目标就是回答:“系统应该如何实现?”,所以总体设计又称概要设计。
- 总体设计以模块为基础,以需求分析阶段得到的数据流图为依据来设计软件结构。
# 软件结构设计准则
软件体系结构设计准则
- 体系结构是对复杂事务的一种抽象
- 体系结构在一定的时间内保持稳定
- 良好的体系结构意味着普通、高效和稳定
软件模块设计准则
- 降低模块之间的耦合性,提高模块的内聚性
- 模块结构的深度、宽度、扇出和扇入适当
- 模块的作用范围应该在控制范围内
- 模块接口设计要简单,以便降低复杂程度和冗余度
- 设计功能可预测并能得到验证的模块
- 适当划分模块规模,以保持其独立性
# 软件设计的概念和原理
模块和模块化
模块是软件结构的基础,是软件元素,能够单独命名、独立完成一定功能的程序语句的集合。
模块化
- 模块化是使得软件能够对付复杂问题所具备的属性。
- 模块化是指解决一个复杂问题时,自顶向下逐层把软件系统划分成若干模块的过程。
- 模块化的目的是为了降低软件复杂性,使软件设计、测试、维护等操作变得简易。
- 运用模块化技术还可以防止错误蔓延,从而可以提高系统的可靠性。
- 模块与外部联系多,模块的独立性差。模块与外部联系少,模块的独立性强。
抽象
模块最重要的特征:
- 抽象
- 信息隐蔽
抽象:过程抽象、数据抽象、控制抽象
信息隐蔽和局部化
信息隐蔽意味着有效的模块化可以通过定义一组独立的模块来实现,这些模块彼此之间仅仅交换那些为了完成系统功能所必须交换的信息。
局部化概念和信息隐蔽是密切相关的。
局部化就是把一些关系密切的软件元素物理地放的彼此靠近。
模块独立性及其度量
模块独立性的概念是模块化、抽象、信息隐蔽和局部化概念的直接结果。
耦合:模块之间相互独立性的度量
- 无直接耦合
- 数据耦合
- 标记耦合
- 控制耦合
- 公共环境耦合
- 内容耦合
尽量使用数据耦合,少用标记耦合和控制耦合,限制公共环境耦合的范围,完全不用内容耦合。
内聚:模块内部各个成分之间彼此结合的紧密程度的度量
- 低内聚
- 偶然内聚
- 逻辑内聚
- 时间内聚
- 中内聚
- 通信内聚
- 高内聚
- 顺序内聚
- 功能内聚
- 低内聚
尽可能做到高内聚,并且能辨认出低内聚的模块。从而通过修改设计提高模块的内聚性,降低模块之间的耦合程度,提高模块的独立性,为设计高质量的软件结构奠定基础。
# 数据库设计
数据库系统的三级模式概念
外模式: 子模式或用户模式
模式:逻辑模式
内模式:存储模式
三级模式之间提供了两层映像
- 外模式 / 模式
- 模式 / 内模式
数据库逻辑设计原则
- 目前 DBMS 产品一般支持 3 种模型:关系、网状、层次
关系数据库规范化
第一范式
- 消除原关系中非主属性对码的部分函数依赖
- 满足第一范式的关系模式并不一定是一个好的关系模式,由于数据冗余度大,有可能出现插入异常、删除异常和修改异常现象
第二范式
- 采用投影分解法将一个 1NF 的关系分解为多个 2NF 的关系
- 消除原关系中非主属性对码的传递函数依赖
- 满足第二范式的关系模式并不一定是一个好的关系模式
- 并不能完全消除关系模式中的各种异常情况和数据冗余
第三范式
- 将一个 2NF 关系分解为多个 3NF 的关系后,并不能完全消除关系模式中的各种异常情况和数据冗余,虽然 3NF 范式,基本上消除了大部分异常问题,但解决的并不彻底,仍然存在改进的余地
- 消除原关系中非主属性对码的部分函数依赖和传递函数依赖
BC 范式
- BCNF 是从 1NF 直接定义而成的
- 规范化的基本思想是逐步消除数据依赖中不合适的部分,使模式中各关系模式达到某种程度的 【分离】,即采用 一事一地 的模式设计原则。
- 在函数依赖范畴,属于 BCNF 的关系模式已经很完美了。
第四范式
- 略
第五范式
- 略
范式化程度过低的关系可能会存在插入异常、删除异常、修改复杂、数据冗余等问题。需要对其进行范式化,转换为高级范式。
但并不意味着范式化程度越高的关系模式越好,在设计数据库模式结构时,如关系模式分解过多,势必在数据查询时要用到较多的连接运算,这样就会影响查询速度。
软件结构设计的图形工具
软件结构图
层次图
HIPO 图
结构化设计方法
数据流图机器类型
结构化设计方法的步骤
变换型数据流图的分析设计
事务型数据流图的分析设计
综合分析设计
- 首先确定数据流图整体上的类型
- 然后利用变换型数据流图的分析方法,先找出主加工,把软件系统分为输入、变换、输出三部分,由此设计出软件系统的顶层和第一层
- 最后根据数据流图各个部分的结构特点,适当地运用 变换分析 或 事务分析,就可得出初始软件结构图的某个方案。
总体设计说明书
引言
- 编写目的
- 项目背景
- 定义
- 参考资料
任务概述
- 目标
- 运行环境
- 需求概述
- 条件与限制
总体设计
- 处理流程
- 总体结构和模块外部设计 (给出软件系统的结构图)
- 功能分配:表明各项功能与程序的关系
接口设计
- 外部接口
- 内部接口
数据结构设计
- 逻辑结构设计
- 物理结构设计
- 数据结构与程序的关系
运行设计
- 运行模块的组合
- 运行控制
- 运行时间
出错处理设计
- 出错输出信息
- 出错处理对策:如设置后备、性能降级、恢复及再启动等
安全保密设计
维护设计
- 说明为方便维护工作的设施,如维护模块
# 本章小结
软件总体设计的基本目的是用比较抽象概括的方式确定系统如何完成预定的任务。总体设计阶段主要由两个小阶段组成:
- 首先进行系统设计,从数据流图出发设想完成系统功能的若干种推荐方案,然后比较分析这些方案,最后和用户共同选定一个最佳方案
- 然后进行软件结构设计,结构化设计方法把软件结构主要划分为交换型和事务型两大类,并且提出与之相应的变换型设计和事务型设计两种方法,以及综合型数据流图的设计方法。
软件结构的模块化设计遵循抽象、信息隐蔽、分解、逐步求精和模块独立性等一系列指导准则。模块独立性是一个良好设计的关键,评价标准主要是模块的耦合和内聚。
数据库设计是指一个给定的应用环境下,确定一个最优数据模型和处理模式,主要包括数据库逻辑结构设计,物理结构设计和数据规范化。
总体设计阶段产生的文档是总体设计说明书,它既是详细设计、编码的基础,也是进行测试的依据之一。
# 软件详细设计
详细设计的目的与任务
详细设计的根本目的就是确定应该怎样具体实现所要求的系统,应该得出对目标系统的精确描述,具体的就是为软件结构图中每一个模块确定采用的算法和块内数据结构,用某种选定的详细设计工具更清晰地描述,从而在编码阶段可以把这些描述直接翻译成某种程序设计语言书写的源程序。
详细设计阶段的任务是要设计出程序的【蓝图】,以后程序员将根据这个蓝图写出实际的代码。
- 因此,详细设计的结构基本上决定了最终程序代码的质量。
- 程序的 "读者" 有两个,即 计算机 和 人 !
- 在整个软件生存周期中,软件测试、诊断程序错误、修改和软件维护等都必须先读懂程序。实际上对于长期使用的软件系统,读程序的时间可能比写程序的时间要长得多。因此,衡量程序的质量不仅仅看它的逻辑是否正确,性能是否满足要求,更重要的是看它是否易读,易理解。
- 结构程序设计技术是实现上述目的的关键技术
结构化程序设计
结构化程序设计所使用的结构有顺序、条件和重复三种,"只有三种基本控制结构就能实现任何单入口单出口,且无死循环、死语句的程序"。
结构化程序设计采用自顶向下,逐步求精的设计方法和单入口单出口的控制结构。
- 逐步求精在总体设计阶段用逐步求精法可以把一个复杂问题解法分解和细化成由许多模块组成的层次结构和软件系统。
详细设计工具
程序流程图
盒图 (N-S 图)
问题分析图(PAD 图)
过程设计语言(PDL)
人机界面设计
无论一个软件的内部结构设计得多好,如果他的人机界面难以理解,那么软件还是失败的。
人机界面设计问题
- 进行人机界面设计时,几乎都有遇到 4 个问题:系统响应时间、用户帮助设施、出错信息处理、命令交互。
- 系统响应时间
- 用户帮助设施
- 出错信息处理
- 命令交互
- 进行人机界面设计时,几乎都有遇到 4 个问题:系统响应时间、用户帮助设施、出错信息处理、命令交互。
人机界面设计原则
- 屏幕界面设计原则可归为 4 点:界面简洁、控件摆放规范、颜色统一、符合用户习惯。
- 让用户驾驭软件,而不是软件驾驭用户
- 尽可能减少用户的记忆负担
- 保持界面的一致性
人机界面设计过程
人机界面设计已经经历了两个界限分明的时代。第一代是以文本为基础的简单交互,如常见的命令行、字符菜单等。第二代是使用图形、语音和其他交互媒介,充分地考虑了人对美的需求。更深高层的界面甚至模拟了人的生活空间,例如,虚拟现实环境。
人机界面设计基本过程可以分为以下步骤:
- 建立任务的目的和意图
- 目标和意图明确后,建立界面需求规格模型
- 以界面需求模型为依据创建用户界面原型
- 用户试用并评估该界面原型
- 设计者根据用户的意见修改设计并实现下一原型
- 不断进行下去、直到用户感到满意为止
详细设计说明书
- 引言
- 编写目的
- 阐明编写详细设计说明书的目的,指明读者对象
- 项目背景
- 应包括项目的来源和主管部门等
- 定义
- 列出文档中用到的专门术语定义和缩写词的原意
- 参考资料
- 列出这些资料的作者、标题、编号、发表日期、出版单位或资料来源,包括项目经核准的计划任务书,合同或批文;项目开发计划;需求规格说明书;总体设计说明书;测试计划(初稿);用户操作手册(初稿);文档所引用的其他资料、软件开发标准或规范。
- 编写目的
- 程序描述
- 功能
- 性能
- 输出和输入项目
- 算法 (模块所选用的算法)
- 程序逻辑
- 详细描述各个模块实现的算法,可以采用流程图、NS 图、PDL 语言、PAD 图、判定表和判定树等描述算法的图表。
- 接口
- 存储分配
- 限制条件
- 测试要点 (给出测试模块的主要测试要求)
本章小结
- 详细设计阶段的任务是确定如何实现所要求的目标系统,将总体设计阶段得到的模块算法用详细设计工具:程序流程图、NS 图、PAD 图和 PDL 语言描述出来,即设计出程序的 "蓝图",从而在下一编码阶段直接翻译成用某种程序设计语言书写的程序。结构化程序设计技术是软件详细设计的基础,任何一个程序都可以用顺序、选择、循环 3 种结构来设计和实现,结构化程序设计具有可理解性和可维护性。
- 人机界面设计质量直接影响用户对软件产品的接受程度,因此,必须对人机界面设计给予足够重视。在人机界面的设计过程中,必须充分重视并认真处理好系统响应时间、用户帮助实施、出错信息处理和命令交互 4 个设计问题。
# 软件编码
程序设计语言的分类
- 基础语言
- 结构化语言
- 面向对象语言
程序设计语言的选择
- 主要的使用标准有如下几条
- 待开发软件的应用领域
- 用户的要求
- 软件的运行环境
- 软件开发人员的知识
- 软件的可移植性要求
程序设计风格
人们在编写程序时,只追求编程的个人技巧,并不重视所编写程序的可读性、可维护性。也就是说人们并不关心源代码的编写风格。只要程序的执行效率、正确就是好程序。但是,随着软件规模的扩大,复杂性的增加,人们逐渐认识到,程序设计风格的混乱在很大程度上制约了软件的发展,并深刻认识到一个逻辑绝对正确但杂乱无章的程序不是好程序,因为这种难以供人阅读的程序,必然难以测试、排错和维护,甚至由于变得无法维护,而提前报废。
程序内部文档
标识符的选取
程序的注解
- 序言性注解
- 序言性注解应该安排在每个模块的首部,用来简要描述模块的整体功能、主要算法、接口特点、重要数据含义以及开发简史等。
- 功能性注解
- 功能性注解主要描述的是程序块,而不是解释每行代码
- 适当使用空行、空格或括号,使读者容易区分程序和注解
- 注解的内容一定要正确、准确,修改程序的同时也应该修改注解。【错误的或不一致的注解不仅对理解程序毫无帮助,而且会引起误导,还不如没有注解!】
- 序言性注解
程序的布局
- 程序代码的布局对于程序的可读性也有很大的影响,应该适当利用阶梯形式,使程序的逻辑结构清晰、易读。
数据说明
- 数据说明的次序应该标准化
语句构造
- 不要为了节省存储空间把多个语句写在同一行
- 尽量避免复杂的条件测试,尤其是减少对 "非" 条件的测试
- 避免大量使用循环嵌套语句和条件嵌套语句
- 利用圆括号使逻辑表达式或算术表达式的运算次序清晰直观
- 变量说明不要遗漏,变量的类型、长度、存储及初始化要正确
- 心理换位:“如果我不是编码人,我能看懂它吗?”
输入 / 输出
- 对所有输入数据都要进行校验
- 检查输入项重要组合的合法性
- 保持简单的输入格式,为方便用户使用
- 输入一批数据时,使用数据或文件结束标志,不要用计数来控制,更不能要求用户自己指定输入项数或记录数。
- 人机交互输入时,要详细说明可用的选择范围和边界值
- 当程序设计语言对输入 / 输出格式有严格要求时,应保持输入格式与输入语句的要求一致
- 输出报表的设计要符合用户要求,输出数据尽量表格化、图形化
- 给有的输出数据加标志,
效率
- 代码效率
- 存储效率
本章小结
编码阶段是将详细设计的每个模块算法转换为用程序设计语言编写的源程序。用程序设计语言编写源程序时,要根据实际项目的特点,既要考虑现实可能性,又要从技术角度、工程角度和心理角度评价和比较各种语言,选择一种合适的程序设计语言。
编码风格直接影响软件的质量,影响软件的可读性、可维护性和可移植性。因此,编码风格要简明和清晰,不要追求所谓程序设计技巧,要注重程序结构清晰,层次结构分明,语言简单明了,各种标识符名字的命名要规范,程序和复杂的数据要有注释。
# 软件测试
软件测试的目标
- 软件测试是为了发现错误而执行程序的过程
- 一个好的测试用例能够发现【至今尚未发现的错误】的测试
- 一个成功的测试是发现了【至今尚未发现的错误】的测试
软件测试的原则
- 软件用例既要有输入数据,又要有对应的输出结果。
- 测试用例不仅要选合理的输入数据,还应选择不合理的输入数据。
- 除了检查程序是否做了它应该做的工作,还应该检查是否做了它不应该做的工作。
- 应该远在测试开始之前就制定测试计划。
- 测试计划、测试用例、测试报告必须作为文档长期保存。
- Pare to 原理说明,测试发现的错误中 80% 很可能是由程序中 20% 的模块造成的,即错误出现的 "群集性" 现象。
- 为了达到最佳的预测效果,程序员应该避免测试自己的程序。测试是一种 "挑剔性" 的行为,测试自己的程序存在心理障碍。另外,对需求规格说明书的理解而引入的错误则更不容易发现。因此,应该由独立的第三方从事测试工作,会更客观,更有效。
软件测试方法及分类
静态测试
- 人工测试
- 计算机辅助静态分析
动态测试
黑盒测试与白盒测试
- 黑盒测试
- 功能测试或数据驱动测试
- 白盒测试
- 结构测试或逻辑驱动测试
软件测试用例的设计
白盒技术
- 逻辑覆盖
- 语句覆盖
- 判定覆盖
- 条件覆盖
- 判定条件覆盖
- 条件组合覆盖
- 路径覆盖
- 循环覆盖
- 单循环
- 嵌套循环
- 基本路径测试
- 逻辑覆盖
黑盒技术
- 等价类划分法
- 有效等价类
- 无效等价类
- 边界值分析法
- 错误推测法
- 因果图法
- 等价类划分法
软件测试过程
软件产品在交付使用之前一般要经历单元测试、集成测试、确认测试和系统测试 4 个阶段的测试。
软件过程中需要 3 类信息
- 软件配置
- 测试配置
- 测试工具
单元测试
- 模块接口测试
- 模块局部数据结构测试
- 模块出错处理通路测试
- 模块中重要的执行路径测试
- 模块边界条件测试
集成测试
- 自顶向下集成方法
- 自底向上集成方法
确认测试
- 有效性测试
- 软件配置报告
系统测试
- 着重对系统的性能、特性进行测试。
α 测试和 β 测试
α 测试
- 指在软件公司进行的由内部人员指导的新产品的测试,经过测试的软件称为 Alpha 版本。
β 测试
- 指公司外部的典型用户在开发者不能控制的环境中 "真实" 应用,并要求用户报告异常情况、提出批评建议,然后对 β 版本进行修正和完善,最终得到正式发布的版本。
调试
- 调试的目的和任务
- 目的:为了解决软件中存在的错误,即错误定位,分析并找出原因改正错误。
- 任务:
- 常用调试技术
- 简单的调试技术
- 消去原因法
- 归纳法
- 演绎法
软件测试阶段终止的条件
- 根据程序的可靠性制定测试的终止条件
- 测试的覆盖率要达到一定的目标
- 规定至少要查出错误数量
# 软件维护
软件维护概述
- 软件维护定义
- 传统上,软件系统交付之后对其实施更改的学科叫做软件维护。
- 通俗地说,软件维护是指软件系统交付使用以后,为了改正软件运行错误,或者因满足新的需求而加入新功能的修改软件的过程。
- 软件维护的分类
- 改正性维护 (Corrective Maintenance)
- 适应性维护 (Adaptive Maintenance)
- 完善性维护 (Perfective Maintenance)
- 预防性维护 (Preventive Maintenance)
- 软件维护的特点
- 软件维护是软件生存周期中延续时间最长、工作量最大的一个阶段
- 软件维护不仅工作量大、任务重,而且维护不当的话,还会产生一些意想不到的副作用,甚至引起新的错误。
- 软件维护活动实际上是一个修改和简化了的软件开发活动。
- 尽管软件维护需要工作量大,但是长期以来,软件维护工作却一直未受到软件设计者们的足够重视。有关软件维护方面的文献资料很少,相应的技术手段和方法也很缺乏。
软件维护的过程
结构化维护与非结构化维护
维护组织
维护工作的流程
- 建立维护机构
- 编写软件维护申请报告
- 确定软件维护工作的流程
- 整理软件维护文档
- 评价软件维护性能
维护工作的组织管理
软件可维护性
- 软件可维护性的定义
- 七大特性衡量程序的可维护性
- 可理解性
- 可测试性
- 可修改性
- 可靠性
- 可移植性
- 可使用性
- 效率
- 七大特性衡量程序的可维护性
- 软件可维护性的度量
- 提高软件可维护性的方法
- 建立明确的软件质量目标和优先级
- 使用提高软件质量的技术和工具
- 模块化方法
- 结构化方法
- 面向对象方法
- 选择便于维护的程序设计语言
- 采取明确的、有效的质量保证审查措施
- 在检查点进行复查
- 验收检查
- 周期性的维护审查
- 对软件包进行检查
- 完善程序的文档
软件维护中存在的问题
- 软件维护困难的表现
- 读懂别人的程序是很困难的,而文档的不足更增加了这种难度。
- 文档的不一致性是软件维护困难的又一要素。
- 软件开发和软件维护在人员和时间上存在差异。
- 软件维护不是一件吸引人的工作。
软件维护的副作用
- 修改代码的副作用
- 修改数据的副作用
- 修改文档的副作用
软件维护的代价
- 系统的大小:系统规模越大,其功能就越复杂,软件维护的工作量也随之增大。
- 程序设计语言:使用强功能的程序设计语言就可以控制程序的规模。
- 系统年龄:
- 数据库技术的应用:
- 先进的软件开发技术:
- 其他的一些因素:如应用的类型、数学模型、任务的难度、开关与标记、if 嵌套深度、索引或下标数等,对维护工作量也有影响。
- 无形的成本
- 一些看起来是合理的修复或修改请求不能及时安排,使得客户不满意
- 变更的结果把一些潜在的错误引入正在维护的软件,使得软件开发工作受到干扰。
- 当必须把软件人员抽调到维护工作中去时,就使得软件开发工作受到干扰。
再工程和逆向工程
软件再工程旨在对现存的大量软件系统进行挖掘、整理,以得到有用的软件构件,或对已有软件构件进行维护,以延长其生存期。
再工程和逆向工程的概念
软件再工程的定义
- 增进对软件的理解
- 准备或直接提高软件的可维护性、复用性或演化性
逆向工程
为什么要实施软件再工程
再工程可帮助软件机构降低软件演化的风险
再工程可帮助软件机构补偿软件的投资
再工程可使得软件易于进一步变更
再工程有着广阔的市场
软件再工程技术
- 改进软件
- 软件重构:
- 文档重写、加注释及文档更新:
- 复用工程:
- 重新划分模块:
- 数据再工程:
- 业务过程再工程:
- 可维护性分析、业务量分析和经济分析:
- 理解软件
- 浏览:
- 分析与度量:
- 逆向工程与设计恢复:
- 获取、保护及扩充软件的已有知识
- 程序分解
- 对象恢复
- 程序理解
- 知识库和程序变换
- 改进软件
再工程和逆向工程
- 软件系统开发完成,经测试达到可靠性指标后,就交给用户,进入软件生存周期的最后一个阶段,即运行维护阶段。软件维护阶段是软件生存周期中时间最长的一个阶段,也是所花费精力和费用最多的一个阶段。软件维护有 4 种类型,即改正性、适应性、完善性和预防性维护。软件维护过程需要建立相应的维护组织,按照一定的维护流程进行结构化维护工作。
- 软件可维护性是衡量软件质量的重要指标,主要通过可理解性、可测试性、可修改性、可靠性、可移植性、可使用性、效率 7 个特性来度量,提高软件可维护性需要从 5 个方面入手完善维护工作。软件维护工作本身的副作用,因此,维护人员更应遵守软件维护流程。
- 软件维护阶段还有一个重要工作是进行软件再工程,实施软件再工程首先需要理解系统,此外还会涉及软件再工程的一些相关技术。

