第三章 软件设计基础
本总结是根据课上老师讲述内容所作笔记
软件设计–解决"如何做"的问题
一 软件设计阶段的任务和目标
设计任务:将需求阶段获得的需求说明(模型)转化为计算机中可实现的系统
设计阶段的主要任务:
- 软件体系结构的设计
- 数据结构的设计
- 用户界面的设计
- 算法的设计
软件设计任务可分为总体设计和详细设计
软件设计的目标:构造一个高内聚低耦合的软件模型 - 高效率
- 高可靠性
- 高可维护性
- 高可理解性
体系结构设计
软件体系结构确定了系统的组织结构和拓扑结构,显示了系统需求和构成系统的元素之间的对应关系,提供了一些设计决策的基本原理。
体系结构的设计过程的主要活动: - 系统分解–将系统分解为若干相互作用的子系统(功能部件)
- 控制建模–建立系统各部分间控制关系的一般模型(功能的连接件)
- 模块分解–将子系统进一步划分为模块
注:往往子系统与模块之间没有明显界限
体系结构设计是软件设计的第一个阶段,该阶段侧重于系统宏观结构的设计,而不关心模块内部算法
体系结构的分类:
一 仓库模型(也叫 容器模型)
- 是一种集中式的模型。各子系统可以直接访问中央数据仓库存储的共享数据。子系统之间紧密耦合。
- 各子系统共享中央数据库中的数据–共享容器模型
- 各子系统可以有自己的数据库,子系统之前通过消息传递实现数据交换
- 优点:
1.共享大数据量的有效方法。
2.子系统不必关心其它的子系统如何使用它所产生的数据。
3.易于将新子系统集成,若新子系统也采用相同规范 - 缺陷:
1.为了共享数据 ,各子系统必须有一致的数据视图 ,不可避免地会影响了整个系统的性能。
2.子系统的改变,使产生的数据结构也可能发生改变。
3.统一的数据库 结构(备份、安全、访问控制和恢复的策 ),将影响子系统的效率。 - 仓库模型中的子系统相互传递消息必须经过中央数据库
二 客户机/服务器模型(C/S结构)
- 是一种分布式模型,采用发请求、得结果的模式
- 客户机:向服务器发出请求(数据请求、网页请求、文件传输请求等)
- 服务器:响应请求,进行相应的操作,将结果回传给客户机,客户机再将格式化后的结果呈现给用户
- C/S结构的应用都由三个相对独立的逻辑部分组成:用户界面<->应用逻辑<->数据访问
- 1.两层客户机/服务器模型
- C/S的工作模式是一种远程过程调用模式,允许客户端和服务器端有不同的软硬平台
- 完整的应用包含三个相对独立的逻辑部分,而两层的C/S结构只有两个端应用。
- 两层C/S架构将数据表示和处理逻辑分开,但应用逻辑和两端之一是紧耦合的,不适宜多用户、多数据库,是非安全的网络环境
- 三级/多级应用模型
- 第一级是数据库管理结点
- 第二级或中间级是"商业逻辑结点",是指具体应用中实施的程序逻辑和法则
- 第三级是用户界面级,强调高效、方便易用的用户界面
- 在多层模型中,中间层会用到应用服务,包括事务服务、消息服务等等。常见的事务服务器有Microsoft Transaction Server,消息服务器有Microsoft Message Queue。
三 分布式对象结构
- 在C/S模型中,客户和服务器在服务/请求上的差别在一定程度上限制了系统的灵活性和可扩展性。
- 对象–提供服务的系统组件
- 每个对象在逻辑上是平等的,他们可以相互为对方提供所需服务
- 提供服务的对象就是服务器,而提出服务请求的对象就是客户
- 软件总线的中间件,即对象请求代理ORB
- 分布式对象结构具有很好的开放性和透明性,用户可以非常方便地在总线上添加、更新或删除组件对象
- 流行的ORB技术标准:CORBA、DCOM (适配器,接口问题:解决:接口不依赖语言和系统,或简单)
- 分布式对象结构具有优良特性:
- 可以在系统部署完成后,再具体考虑服务的分布和如何提供服务的问题
- 具有开放式结构,提供了极好的灵活性和可伸缩性
- 系统可进行动态分配
四 抽象机模型(分层模型)
通常用于建立子系统的接口模型,每一层提供一组服务,每层定义一个抽象机。例如:网络的五层模型、七层模型
- 优点:支持增量式开发
- 缺点:系统构成、性能保证比较困难(但有灵活性)
五 控制模型
考虑子系统之间的控制流。
控制方式:
- 集中式控制
- 事件驱动系统–由外部产生的事件来驱动系统
- 广播模型
- 中断驱动的模型
软件设计阶段
分为总体设计和详细设计
设计阶段结束要交付设计说明书,每个设计步骤完成都要进行复审。
常用设计方法:SD法、Jackson法、OOD法、HIPO法、Parnas法、Warnier法等
软件设计准则
- 软件结构的准则
- 软件机构表示软件的系统结构,他是软件模块间关系的表示,均表示为层次关系
- 一个好的软件结构的形态准则是:顶部宽度小,中部宽度最大,底部宽度次之;在结构顶部有较高的扇出数,在底部有较高的扇入数。
- 模块化准则
- 模块化就是将系统划分成若干模块,每个模块完成一个子功能,把这些模块集中起来组成一个整体,以满足所要求的整个系统的功能
- 我们利用模块化来降低软件复杂度。注意选择分解的最佳模块数
- 软件独立性准则
- 开发具有功能专一,模块之间无过多相互作用的模块。又称为模块独立性准则
- 这种类型的模块可以并行开发,开发容易,能减少错误的影响,使模块容易组合、修改及测试
- 软件独立性的度量标准是两个定性指标:
- 耦合性 用于描述模块之间联系的紧密程度
- 内聚性 用于描述模块内部联系的紧密程度
内聚度:模块内部各成分彼此结合的紧密程度。
- 内聚度按其高低程度可分为七级,内聚度越高越好,功能越单一。
耦合度:软件结构中模块间关联程度的一种度量。 - 耦合的强弱取决于模块间接口的复杂性、进入或调用模块的位置以及通过界面传送数据的多少等。
- 设计软件应追求尽可能松散耦合的系统。
- 松散耦合系统中,任一模块的设计、测试和维护都相对独立。
- 松散耦合系统模块间联系较少,错误在模块间传播的可能性随之变小。
- 模块间的耦合程度直接影响系统的可理解性、可测试性、可靠性和可维护性。
- 耦合度分七级,耦合性越高,模块独立性越弱
追求高内聚低耦合!
结构化设计方法
一.SD法
- 两个阶段:总体设计
- 任务
- 文档
1.从DFD图导出初始的模块结构图SC
- 中心变换型–变换分析
- 事物处理型–事务分析
2.按照SD法设计总则…
降低块间联系,提高块内联系。
改进:1.尽可能建立功能模块(执行某项任务的部分、出错处理部分、返回结束标志)
模块的作用范围
模块大小适当
模块的扇入扇出数不宜太多
详细设计
一.任务
二.常用描述方法工具
1.流程图
2.结构化流程图 N-S图
- 由顺序、选择、循环三种基本结构组成
- 循序结构、选择结构、多分支选择结构、当型循环、直到型循环、后判定型循环结构、先判断型循环结构
3.PAD图–问题分析图
基本控制循环结构 - 顺序结构
- 选择结构
- 多分支选择结构
- 后判定型循环结构
- 先判断型循环结构
4.PDL语言
用户界面设计 --以人为本
- 用户界面应具有的特性 --友好的
- 用户界面设计的任务 --用户界面设计应完成的工作
- 用户界面的基本类型 --用户界面的工作模式
用户界面设计原则
- 可视性和可支付性
- 保持命令、菜单、颜色等统一
- 为频繁使用的用户提供快捷方式
- 提供信息反馈
- 提供简单的错误处理
- 方便的操作、回滚
- 降低短期记忆回忆
交互性是用户界面最重要的特性
按照交互方式分为五类:…
用户界面基本类型
- 菜单
- 按照显示方式分
- 按屏幕位置和操作风格
- 图像
- 方便可视化
- 图像的隐蔽和再现
- 屏幕滚动和图案显示
- 动画
- 对话框
- 窗口(视图区)
数据I/O界面设计
主要从输入速度和减少出错率考虑
- 尽量减少输入工作量
- 输入屏幕与输入格式匹配
- 数据输入的一般规则
4.1 程序设计语言的选择
程序设计语言分类
- 低级语言(机器语言和汇编语言)
- 高级语言
程序设计语言选择准则
- 项目应用领域
- 算法和计算复杂性
- 软件的执行环境
- 性能因素
- 数据结构的复杂性
- 软件开发人员的知识水平以及心理因素
结构化程序设计方法,即SP法是结构化开发方法的重要组成部分(最短距离)
基本思想:
- 自顶向下、逐步求精
- 单入口和单出口
软件优化方法:
- 不考虑时间因素的前提下开发并精简软件结构
- 寻求软件设计中的关键路径和关键事件
- 选择合适高级编程语言
- …
程序设计风格 - 代码文件
- 符号名的命名
- 源程序中的注释
- 注意源程序的书写格式
- 语句构造方法
- 数据说明方法
- 输入输出技术
- 输入输出格式应该尽可能统一
算法与程序效率
设计逻辑结构清晰、高效的算法,是提高程序效率的关键
影响程序效率的因素
- 算法对效率的影响
- 存储效率
- 输入输出效率
软件代码审查 - 程序的版式
- 文件结构
- 命名规则
- 表达式与基本语句
中心变换型的DFD图可看成是对输入数据进行转换而得到输出数据的处理,因此可以使用事务分析技术得到初始的模块结构图?(错误,混淆概念)
两型:中心变换型 事务分析型
第五章 软件测试
一. 软件测试目的:为了发现和改变错误
二. 软件测试的特点:
- 软件测试开销大
- 不能进行"穷举"测试
- 软件测试难度大 —高效的测试用例
三 软件测试的基本原则
- 尽量不由程序的设计者测试
- 关键是注重测试用例的选择
- 输入数据的组成(输入数据、预期的输出结果)
- 既有合理输入数据,也有不合理的输入数据。
- 用例既能检查应完成的任务,也能够检查不应该完成的任务。
- 长期保存测试用例。
- 充分注意测试中的群集现象
四 测试基本步骤
- 预测试:概要设计审查->详细设计审查->代码审查
- 测试:模块测试(单元测试)->整体测试(组装测试)->功能测试(有效性测试)->系统测试(确认测试)->验收测试->安装测试
软件测试方法分为两类:静态分析、动态测试
静态测试方法
指以人工的、非形式化的方法对程序进行分析和测试。
- 桌前检查
- 代码会审
- 步行检查
步行检查时,还常使用以下分析方法:
① 调用图
从语义的角度考察程序的控制路线。
② 数据流分析图
检查分析变量的定义和引用情况。
动态测试方法
通过选择适当测试用例,执行程序
常用:
- 白盒法
- 分析程序的内部逻辑结构,注意选择适当的覆盖标准,设计测试用例,对主要路径进行尽可能多的测试
- 白盒法又称为逻辑覆盖法,其测试用例选择,是按照不同覆盖标准确定的
- 白盒法常用的覆盖标准
① 语句覆盖: 选择足够的测试用例,使得程序中每个语句至少都能被执行一次。
② 判定覆盖: 执行足够的测试用例,使得程序中每个判定至少都获得一次“真”值和“假”值。
③ 条件覆盖:执行足够的测试用例,使得判定中的每个条件获得各种可能的结果。
④ 判定/条件覆盖: 执行足够的测试用例,使得判定中每个条件取到各种可能的值,并使每个判定取到各种可能的结果。
⑤ 条件组合覆盖: 执行足够的测试用例,使得每个判定中条件的各种可能组合都至少出现一次。
ps:先写一个语句覆盖,再按不同要求补充或删除 - 白盒法步骤
1)选择逻辑覆盖标准。
2)按照覆盖标准列出所有情况。
3)选择确定测试用例。
4)验证分析运行结果与预期结果
- 黑盒法
- 不考虑程序的内部结构与特性,只根据程序功能或程序的外部特性设计测试用例。
- 等价分类法
- 基本思想:根据程序的I/O特性,将程序的定义域划分为有限个等价区段 —“等价类”,从等价类中选择出的用例,具有“代表性”
- 等价类分为:
- 有效等价类 — 对于程序的规格说明,是合理的、有意义的输入数据构成的集合。
- 无效等价类 —对于程序的规格说明,是不合理的、没有意义的输入数据构成的集合。
- 等价分类法的步骤:
① 划分“等价类”
应按照输入条件(如输入值的范围,值的个数,值的集合,输入条件必须如何)划分为有效等价类和无效等价类。
② 选择测试用例
A 为每个等价类编号;
B 使一个测试用例尽可能覆盖多个有效等价类
C 特别要注意:一个测试用例只能覆盖一个无效等价类。
- 边值分析法
- 基本思想: 选择等价类的边缘值作为测试用例,让每个等价类的边界都得到测试,选择测试用例既考虑输入亦考虑输出。
- 分析步骤:
A 先划分等价类。
B 选择测试用例,测试等价类边界 - 边界选择原则:
A 按照输入值范围的边界。
B 按照输入/输出值个数的边界。
C 输出值域的边界。
D 输入/输出有序集的边界。
- 错误推测法
凭经验或直觉推测可能的错误,列出程序中可能有的错误和容易发生错误的特殊情况,选择测试用例 - 因果图法
- 把输入条件视为“因”,把输出条件视为“果”,将黑盒看成是从因到果的网络图,采用逻辑图的形式来表达功能说明书中输入条件的各种组合与输出的关系。根据这种关系可选择高效的测试用例。
- 因果图是一种形式化语言,是一种组合逻辑网络图。
⑴ 因果图的基本符号
0 - 表示“不出现” 1 - 表示“出现” - 恒等
若a为1,则b为1,否则b为0。- “非”函数
若a为1,则b为0,否则b为1。 - “或”函数
若a或b为1,则d为1,否则d为0。 - “与”函数
若a与b同为1,则d为1,否则d为0
- “非”函数
对“与”、“或”函数的限制符号
- E约束(异)— 排斥
即a、b不能同时为1。- I约束(或)— 包容
a、b、c不能同时为0。 - O约束(唯一)— 选一
a、b中仅有一个为1。 - R约束(要求)— 需要
a为1时,b必须为1 - M约束(强制)— 屏蔽
若a为1时,则b强制为1。
⑵ 因果图法的步骤
- I约束(或)— 包容
- 分析规范,即将问题分为若干可工作的步骤。
- 标识出规范中的原因与结果。
原因—输入条件
结果—输出或系统变换 - 分析规范语义、内容,转换为因果图。
- 将因果图转换为有限项判断表。
- 将判断表的每一列,转换为一个测试用例。
软件测试的步骤
测试步骤及策略:
所有测试过程都应采用综合测试策略;即先作静态分析,再作动态测试。并事先制订测试计划。测试过程通常可分4步进行:
单元测试->集成测试->确认测试->系统测试
一. 模块测试步骤
考虑到被测模块与其它模块的联系,因此测试时需要使用两类辅助模块来模拟其他模块
- 驱动模块(driver)— 模拟主程序功能,用于向被测模块传递数据,接收、打印从被测模块返回的数据。
- 桩模块(stub)— 又称为假模块,用于模拟那些由被测模块所调用的下属模块功能。
- 一般,驱动模块比桩模块容易设计。但都是额外开销。测试方法以白盒法为主。
二. 组装测试(Integration Testing)
也称为联合测试或集成测试,重点测试模块的接口部分,需设计测试过程使用的驱动模块或桩模块
- 装测试的任务
①确定模块组装方案,将经过测试的模块组装为一个完整的系统。组装方案分为渐增式及非渐增式。
②测试方法以黑盒法为主,按照组装方案进行测试 - 渐增式组装测试
渐增式是先进行模块测试,然后将这些模块逐步组装成较大的系统,每连接一个模块进行一次测试。两种方案:
- 自顶而下增值
- 自底而上增值
设计驱动模块或桩模块,对每一个新组装的子系统进行测试,对发现问题较多的子系统或模块应该用白盒法作回归测试。
无论是自顶而下增值还是自底而上增值,还可选择深度优先或者宽度优先增值。
确定集成过程的原则
- 自顶而下增值
优点:能够尽早发现系统主控方面的问题。
缺点:无法验证桩模块是否完全模拟了下属模块的功能。 - 自底而上增值
优点:驱动模块较容易编写桩模块,能够尽早查出底层涉及较复杂的算法和实际的I/O模块中的错误。
缺点:最后才能发现系统主控方面的问题。 - 集成过程的原则
① 尽早测试关键模块。
② 尽早测试包含I/O的模块
- 混合增值
常见的混合增值方案:
- 衍变的自顶而下
先自底而上集成子系统,再自顶而下集成总系统。 - 自底而上—自顶而下增值
对含有读操作的子系统采用自底而上。
对含有写操作的子系统采用自顶而下。 - 回归测试
在回归测试中自底而上,对其余部分(引起是对修改过的子系统)采用自顶而下。
三、确认测试(validation testing)
-
任务
又称为有效性测试或功能测试。其任务是验证系统的功能、性能等特性是否符合需求规格说明。 -
确认测试步骤
(1)有效性测试
制定测试计划,运用黑盒法,验证软件特性是否与需求符合。
(2)软件配置复查
软件配置—指软件工程过程中所产生的所有信息项:文档、报告、程序、表格、数据。随着软件工程过程的进展软件配置项(SCI software Configuration Item)快速增加和变化。应复查SCI是否齐全。
(3) α α α测试和 β β β测试一般都应该先进行静态测试,再考虑动态测试。