第 6 章 软件设计
DESCRIPTION
第 6 章 软件设计. 需求分析阶段:系统需要做什么 软件设计阶段的目标:系统需要怎么做 经过了需求分析,得出了用数据流图,数据字典,实体联系图描述的系统逻辑模型,已经知道了 “ 做什么 ” ,但是究竟 “ 怎么做 ” ,还必须进行总体设计和详细设计,在总体设计这一步需要做两件事,( 1 )根据在需求分析阶段得到的数据流图可以确定系统的具体实现方案, 划分组成系统的物理元素,程序、文件、数据库、人工过程、文档等。 ( 2 )确定软件结构,即确定程序是由哪些模块组成的,以及模块之间的关系。. 二、软件设计的基本原理 1 、模块化 - PowerPoint PPT PresentationTRANSCRIPT
第 6章 软件设计
需求分析阶段:系统需要做什么软件设计阶段的目标:系统需要怎么做 经过了需求分析,得出了用数据流图,数据字典,实体联系图描述的系统逻辑模型,已经知道了“做什么”,但是究竟“怎么做”,还必须进行总体设计和详细设计,在总体设计这一步需要做两件事,( 1)根据在需求分析阶段得到的数据流图可以确定系统的具体实现方案,划分组成系统的物理元素,程序、文件、数据库、人工过程、文档等。( 2)确定软件结构,即确定程序是由哪些模块组成的,以及模块之间的关系。
二、软件设计的基本原理 1 、模块化 模块化是指将程序划分成多个模块,每个模块完成一个子功能。 模块:又称构件,是能够单独命名并独立地完成一定功能的程序语句的集合。例如高级语言中的过程、函数、子程序等都可作为模块。 模块化是软件的一个重要属性。模块化的特性提供了人们处理复杂的问题的一种方法,同时也使得软件能够被有效地管理。
模块的性质:( 1 )简明性,简单易懂,易于实现( 2 )完整性,可以实现一个完整的功能,同时可以被单独地编程、测试等。( 3 )独立性,理想的模块相互之间是独立的,有很少的联系,对外只保留接口,改变其内容结构不会地外部程序产生影响。
有两个函数: C(x) 表示问题 x 的复杂程度; E(x) 表示解决问题 x 所需要的工作量(时间)。
对于两个问题 P1 和 P2 ,如果: C(P1) > C(P2)
则: E(P1) > E(P2)
另一个特性是: C(P1 + P2) > C(P1) + C(P2)
根据前面的结论,我们可以得出下面的不等式:
E(P1 + P2) > E(P1) + E(P2)
这个不等式表明:单独解决问题 P1 和 P2 所需的工作量之和,比把 P1 和 P2 合起来作为一个问题来解决时所需的工作量要少。
这种“分而治之”的思想提供了模块化的根据:把复杂的问题分解成许多容易解决的小问题,原来的问题也就容易解决了。
模块化和软件成本的关系
M
软件总成本 成本或工作量
最小成本区
接口成本
模块数目
各模块成本之和
应用模块化设计方法可以将程序分解为适当的模块数目,以使总的开发成本最小。还可以将难的模块分给熟练的程序员。
2 、抽象
我们在考虑问题时,集中考虑和当前问题有关的方面,而忽略和当前问题无关的方面,这就是抽象。或者说抽象就是抽出事物的本质特性而暂时不考虑它们的细节。
软件工程过程的每一步,都是对软件解法的抽象层次的一次细化。在可行性研究阶段,软件被看作是一个完整的系统部分;在需求分析期间,我们使用在问题环境中熟悉的术语来描述软件的解法;当我们由总体设计阶段转入详细设计阶段时,抽象的程度进一步减少;最后,当源程序写出来时,也就达到了抽象的最低层。
3 、逐步求精 所谓逐步求精是指为集中精力解决主要问题而尽量推迟对问题细节的考虑。 原因:一个人在任何时候都只能把注意力集中在( 7±2 )个知识块上。
4、信息隐藏
信息隐藏原理认为:模块所包含的信息(过程和数据)对于其他模块来说应该是隐藏的。也就是说,模块应当被这样规定和设计,使得包含在模块中的信息(过程或数据)对于其它不需要这些信息的模块来说,是不能访问的,或者说是“不可见”的。
信息隐藏对于软件的测试与维护都有很大的好处。因为对于软件的其它部分来说,绝大多数数据和过程都是隐藏的,这样,在修改期间由于疏忽而引入的错误所造成的影响就可以局限在一个或几个模块内部,不至波及到软件的其他部分。
四、 软件的度量 软件的度量主要指模块内程序的复杂性。它直接关联到软
件开发费用的多少,开发周期的长短和软件内部潜伏错误的多少。同时它也是软件可理解性的另一种度量。 减少程序复杂性,可提高软件的简单性和可理解性,并使
软件开发费用减少,开发周期缩短,软件内部潜藏错误减少。(1) 代码行度量法 度量程序的复杂性,最简单的方法就是统计程序的源代码
行数。此方法基于两个前提: 程序复杂性随着程序规模的增加不均衡地增长; 控制程序规模的方法最好是采用分而治之的办法。将一个大程序分解成若干个简单的可理解的程序段。
(2) Halstead方法(霍尔斯特德) Halstead方法采用以下一组基本的度量值,这些
度量值通常在程序产生之后得出。① 实际的 Halstead 长度 设N1为程序中实际出现的运算符总次数,N2 为程序中实际出现的操作数总次数,n1表示程序中不同运算符(包括保留字)的个数,n2 表示程序中不同运算对象的个数。N为程序长度,其中 N = N1 + N2 。
词汇量 n=n1+n2
程序量
V=(N1 + N2)log2(n1+n2)
Halstead方法经常用来预测程序中的错误 , 认为程序中可能存在的差错应与程序的容量成正比。预测公式为
B = ( N1 + N2 ) log2 ( n1 + n2 )∕3000
(3) McCabe度量法(麦凯布) McCabe度量法是一种基于程序控制流的复杂性度量方法。 McCabe定义的程序复杂性度量值又称环路复杂度,它基于一个程序模块的程序图中环路的个数。 如果把程序流程图中每个处理符号都退化成一个结点,原来联结不同处理符号的流线变成连接不同结点的有向弧,这样得到的有向图就叫做程序图 ,也叫做流图。计算有向图 G的环路复杂性的公式有如下三种方法:( 1)环形复杂度等于流图中区域数。( 2)流图中的环形复杂度 V(G) = m- n+ 2其中, m是图 G中有向弧个数, n是图 G中结点个数。 ( 3)流图 G的环形复杂度 V( G)= P+ 1,其中 P是判定结点的数目。
1
2
3
6 4
57 8
总边数为 11,节点数为 9,所以环形复杂度为 11 - 9+ 2= 4区域数为 4,判定结点有 3,所以它们的环形复杂度都是 4
1
2 , 3
4 、 56
7 8
9
1011
五、软件设计的基本原理1、抽象与求精2、模块化和信息隐藏3 、模块独立性
模块独立性
为了降低软件的复杂性,提高可理解性,可维护性,必须把系统划分为多个模块,但模块不能任意划分,应尽量保持其独立性,模块独立性是指每个模块只完成系统要求的独立的子功能,并且与其他模块的联系最少且接口简单。模块独立性概念是模块化、抽象及信息隐藏等原理的产物。
模块的独立性可由两个标准来度量,它们是耦合和内聚,所谓的内聚性是指一个模块内各个元素彼此结合的紧密程度。而耦合是指各模块之间相互联系的紧密程度。
内聚度(又叫内聚性) 所谓内聚性是指一个模块内各个元素彼此结合的紧密程度。 内聚一般可分为如下几种:偶然内聚,逻辑内聚,时间内聚,过程内聚,通信内聚,顺序内聚,功能内聚。 偶然内聚,是指模块各处元素之间没有任何联系, 逻辑内聚,是指模块内执行几个逻辑上相邻的功能,通过参数决定该模块完成哪个功能,如产生各种类型错误的信息输出放在一个模块,即一个单入口多功能模块。 时间内聚,是指把需要同时执行的动作组合在一起形成的模块,比如可以将初始化语句放到一个模块。
过程内聚,是指一个模块内的处理元素是相关的,而且必须以特定次序执行,这个模块完成特定的功能。 通信内聚,是指模块各部分都紧密相关于同一数据(或数据结构)。即所有的元素都使用同一个输入数据或产生同一个输出数据。 顺序内聚,是指模块内各处理元素密切相关于同一功能,且必须顺序执行,前一功能元素的输出就是下一功能元素的输入。 功能内聚,是指模块内所有的元素共同完成一个功能,缺一不可。 在系统设计时设法提高系统的内聚程度,而降低系统的耦合程度。
1、耦合 耦合:软件结构中各个模块之间相互关联程度的度量。
常见的耦合:
( 1)非直接耦合( 2)数据耦合( 3)控制耦合( 4)特征耦合( 5)公共耦合( 6)内容耦合 设计原则:尽量使用数据耦合,少用控制耦合,限制公共耦合的范围,避免使用内容耦合。
非直接耦合,是指模块之间没有直接的关系。 数据耦合,是指模块之间有调用关系,但传递的只是简单的数据,例如高级语言里面的数据值等。 控制耦合,是指一个模块调用另一个模块时,传递的是控制变量(如开关、标志等),被调用模块根据该控制变量有选择地执行块内某一功能,所以被调用模块内应该有多种功能,至于执行哪一功能被执行,要受调用模块的控制。 特征耦合,是指将整个数据结构作为参数传递,但是被调用模块只需要其中的一部分数据。
公共耦合:是指通过一个公共数据环境相互作用的那些模块的耦合,这些公共数据环境可以是全局变量或数据结构,共享内存区等。 内容耦合:如果出现以下情况之一,则为内容耦合 ( 1 )一个模块访问另一个模块的内部数据。 ( 2 )一个模块不通过正常入口而转到另一个模块。 ( 3 )两个模块有一部分代码重叠。 ( 4 )一个模块有多个入口。 设计原则:尽量使用数据耦合,少用控制耦合,限制公共耦合的范围,避免使用内容耦合。
六、软件设计过程中的几条规则 1 、提高模块的独立性,提高模块的内聚程度而降低模块的耦合程度。 2 、模块规模应该适中,模块太大,则不容易理解,而模块太小,则接口太复杂。 3 、深度,宽度,扇出和扇入适当。 所谓深度是指软件结构中控制的层数。 而宽度是指软件结构内同一个层次上的模块总数的最大值。 扇出是指一个模块直接调用的模块总数。 扇入是指有多少个上级模块调用该模块。
4 、模块的作用域应该在控制域内,即模块的作用范围应该在它的控制域之内。
所谓模块的作用域是指受模块内的一个判定影响的所有模块的集合。
所谓模块的控制域是指模块本身及所有直接或间接从属于它的模块的集合。
例如: A 的控制域为 A 、 B 、 C 、 D 、 E 、 F ,则 A 的作用域应该在控制域范围之内。
M
A
D F
G
E
CB
5 、力争降低模块接口的复杂程度。模块之间所传递的参数应该很明确。
6 、设计单入口单出口的模块。模块之间不要出现内容耦合。
7 、模块的功能应该可以预测。对于一个模块,对于相同的输入,会产生相同的输出,则这个模块的功能就是可以预测的。(带有内部存储器的模块是不可预测的,因为它的输出依赖于存储器的状态)。
四、描绘软件结构的图形工具 1 、层次图:层次图的一个矩形框代表一个模块,方框间的边线表示调用关系。
正文加工系统
输入 输出 编辑 加标题 存储 检索 编目录 格式化
添加 删除 插入 修改 合并 列表
正文加工系统
输入1.0
输出2.0
编辑3.0
加标题4.0
存储5.0
检索6.0
编目录7.0
格式化8.0
添加3.1
删除3.2
插入3.3
修改3.4
合并3.5
列表3.6
可以在层次图的方框上加编号,每个带编号的模块再加一个 IPO图,这样就形成了 HIPO图。
3 、结构图 在结构图中除了表示模块之间调用关系以外,还用带注释的箭头表示模块调用过程中来回传递的信息。其中带空心的箭头表示数据信息,而带实心的箭头表示传递控制信息。软件结构图的基本符号如下:
A
B
(a) 基本形式
A
CB D
(b) 顺序
A
B C
(c) 选择
A
B
(d) 重复
格式化的解
解
产生最佳解
计算最佳解得到好输入
编辑输入读输入
原始输入 编辑结果原始输入
输出结果
显示结果结果格式化
解 格式化的解
好输入 好输入
解
产生最佳解的结构图
三、过程设计的工具 过程设计工具:描述程序处理过程的工具。 过程设计的工具一般有六种,可以选择使用: ( 1 )程序流程图; ( 2 )盒图; ( 3 ) PAD图; ( 4 )判定表,判定表主要用来表示含有多重嵌套的条件选择; ( 5 )判定树; ( 6 )过程设计语言。
一、程序流程图
起止端点 数据 处理 准备或预处理 预先定义的处理
条件判断 循环上界限 循环下界限 文档 流线
虚线 省略符 并行方式 注释 控制流
程序流程图虽然比较直观,灵活,并且比较容易掌握,但是它的随意性和灵活性却使它不可避免地存在着一些缺点: ( 1)由于程序流程图的特点,它本身并不是逐步求精的好工具。因为它使程序员容易过早地考虑程序的具体控制流程,而忽略了程序的全局结构; ( 2 )程序流程图中用箭头代表控制流,这样使得程序员不受任何约束,可以完全不顾结构程序设计的精神,随意转移控制; ( 3)程序流程图在表示数据结构方面存在不足。
例 1 打印 A, B, C 三数中最小者的程序
输入 A 、 B 、 C
值 1
Case1
部分
Case条件 第一个任务
第二个任务
第三个任务
(a) 顺序结构
F 条件 T
ELSE
部分 THEN
部分
(b) 选择结构 (c) 多分支结构
循环条件
DO_WHILE
部分
循环条件
DO_UNTIL
部分
(d) 循环结构
A
(e) 调用子程序 A
值 2
Case2
部分
…
值 n
Casen
部分
盒图( N-S图)
N-S图有以下一些特点:( 1 )功能域(即某一个特定控制结构的作用
域)有明确的规定,并且可以很直观地从 N-S图上看出来;
( 2 )它的控制转移不能任意规定,必须遵守结构化程序设计的要求;
( 3 )很容易确定局部数据和全局数据的作用域;( 4)很容易表现嵌套关系,也可以表示模块的
层次结构。
A
B
(a) 顺序结构
A
B C
(b) 选择结构
WHILE P S
(c) WHILE型循环结构
UNTIL P S
(d) UNTIL型循环结构
A1
A2
P=
An
…
P1
P2
Pn
(e) 多分支结构
(f) 语句标号
(g) 定义
PAD图( problem analysis diagram)
A
C
B1
B2 P1
WHILE P3 C4
C def
C1
C2
C3 P2
PAD图提供的定义功能和逐步求精功能
一、总体设计过程 总体设计过程一般包括九个步骤,实际上主要做以下几部分工作: ( 1 )需求分析得到了软件的逻辑模型,用数据流图来表示,将数据流图划分为不同的部分,可以得到不同的物理实现方案。 ( 2 )从这些方案里选取合理的方案,除去经济、技术方面不合理的方案。 ( 3 )从合理的方案里面选取最佳的方案。 ( 4 )对数据流图中的处理进行功能分解,如果一个处理太复杂,则将它分解成多个处理。
( 5 )设计软件结构,由数据流图得出用层次图或结构图表示的软件结构。将整个系统用清晰的调用关系表示出来。 ( 6 )如果涉及到数据库,则应设计数据库。 ( 7 )制定测试计划,在早期制定测试计划,可以提高软件的可测试性。 ( 8 )书写文档,包括用细化的数据流图,用层次图表示的软件结构,测试计划,详细实现计划,数据库设计结果等。 ( 9 )对总体设计进行严格的技术审查。
面向数据流图的设计方法 所谓数据流图是指信息流和数据从输入到输出的过程所经历的变换。数据流图的类型: 1、变换型数据流图
输入变换
输出
变换型数据流是指外部信息输入到系统,信息经过变换中心,加工处理后再沿输出通路变换成外部形式离开软件系统。
2 、事务型数据流图
事务中心
活动通路T
事务
所谓事务型数据流图是指事务沿某个通路到达一个处理,该处理根据输入类型在若干个动作序列中选出一个来执行。事务中心所要完成的任务包括( 1)接收数据,( 2)分析每个事务,确定其类型,( 3)根据事务类型,选择一条活动通路。
复查
满意
精化数据流图
类型
区分事务中心和数据接收通路
映射成事务结构
区分输入和输出分支
映射成变换结构
“ ”事务 “ ”变换
优化软件结构
导出软件结构
详细设计
不满意
事务分析变换分析
面向数据流图的设计过程
变换分析:所谓变换分析是指将具有变换流特点的数据流图按预先确定的模式映射成软件结构。 一个汽车数字仪表板的设计过程。假设仪表板的功能如下:( 1)通过模/数( A/ D)转换实现传感器和微处理机接口;( 2)在发光二极管( LCD)面板上显示数据;( 3 )指示每小时英里数( mph),行驶的里程,每加仑油行驶的英里数( mpg)等等;( 4)指示加速或减速;( 5)超速警告:如果车速超过 55英里/小时,发出超速警告铃声。 在软件需求分析阶段,应该对上述每项性能和其它要求进行全面的分析,并建立起相应的文档资料,得出数据流图。具体的设计步骤如下:
△SPS
mph
超速值
计算里程
产生加速/减速显示
读入旋转信号
收集并求平均
旋转信号
信号数 /秒(SPS)
确定加速/减速 箭头指示
下箭头
水平线上箭头转换成
转/分(rpm)
计算mph 和超速值
计算燃料消耗
产生mpg显示
读入并核实
计算gph
燃料流量传感器信号
燃料流量
gphmph
mpg
mpg 显示
产生里程显示
英里
显示发出警告铃声
警告铃声
产生mph显示
mph 显示
rpm
△SPS
rpm
1、复查基本系统模型:确定输入数据和输出数据符合实际。
2、精化数据流图:使数据流图中每个处理代表一个规模适中的独立的子功能。 mile
3 、确定数据流图的类型 这一步的任务是确定数据流图是变换型数据流图还是事务型数据流图。 从上图中可以看出,数据沿着两条输入通路(旋转信号和燃料流量传感器信号)进入系统,然后沿着五条通路( 4个显示,一个警告铃声)离开,没有明显的事务中心(虽然变换“计算 mph与超速值”可以看作是一个事务中心)。因此,可以认为这个数据流图的类型是变换型数据流图。
4、确定输入流和输出流的边界,从而孤立出变换中心
△SPS
rpm
mpg 显示
gph
mpg
mph
(SPS)
mph
超速值
计算里程
读入旋转信号
收集并求平均
旋转信号
信号数 /秒确定
加速 /减速 箭头指示
产生加速/ 减速显示 下箭头
水平线上箭头
转换成转 /分(rpm)
计算mph 和超速值
计算燃料消耗
产生mpg显示
读入并核实
计算gph
燃料流量传感器信号
燃料流量 产生里程显示
英里
显示发出警告铃声
警告铃声
产生mph显示
mph 显示
SPS
rpm
5 、进行“第一级分解”
Cm
CtCa Ce
将整个控制模块分为三部分:输入模块、变换中心模块及输出模块。
数字仪表板控制
数据转换控制
接收传感器信号
驱动仪表板
输入控制 变换控制 输出控制
第一级分解的结果
第二级分解
B
A
D C
Cm
Ca
C B
D
A
第二级分解的方法:沿边界分别向外,每个处理转换为一个模块
接收 传感器信号
转换成 rpm 计算 gph
收集 sps
读旋转信号
读燃料流量
数据转换控制
确定 加速/减速 计算 mph 计算 mpg 计算里程
未经精化的输入结构 未经精化的变换结构
△ SPS
rpm
mpg 显示
gph
mpg
mph
(SPS)
mph
超速值
计算里程
读入旋转信号
收集并求平均
旋转信号
信号数 /秒
确定加速 /减速 箭头指示
产生加速/ 减速显示 下箭头
水平线上箭头
转换成转 /分(rpm)
计算mph 和超速值
计算燃料消耗
产生mpg显示
读入并核实
计算gph
燃料流量传感器信号
燃料流量 产生里程显示
英里
显示发出警告铃声
警告铃声
产生mph显示
mph 显示
SPS
rpm
驱动仪表板
加速/减速显示 显示 mpg 显示里程 发出警告铃声显示 mph
发光二极管显示
未经精化的输出结构
7 、使用设计度量和设计准则对第一次分割得到的软件结构进一步精化 对于从前面的设计步骤得到的软件结构,还可以进行许多修改:( 1)输入结构中的模块“转换成 rpm” 和“收集 sps”可以合并;( 2 )模块“确定加速/减速”可以放在模块“计算 mph”下面,以减少耦合;( 3 )模块“加速/减速显示”可以相应地放在模块“显示 mph”的下面。
数字仪表板控制
接收传感器信号
数据转换控制 驱动仪表板
计算里程
计算mpg
计算mph
计算gph
转换成rpm
发出警报铃声
显示里程
显示mpg
显示mph
读旋转信号
读燃料流量
确定加速/减速
加速/减速显示
发光二极管显示
精化的数字仪表板系统的软件结构
A_CTL
调度
调度
接收通路
C通路B通路
总控
A通路
B_CTL
调度C_CTL
调度
事务分析
设计后的处理:
在确定系统的软件结构以后,还必须做好下述工作:
· 为每个模块开发一份功能说明;
· 为每个模块提供一份接口说明;
· 定义局部的和全程的数据结构;
· 给出所有的设计限制或约束;
· 进行总体设计评审;
· 如果需要和可能的话,进行设计“优化”。