需求分析模型 -> 设计模型
结构化设计方法
转换过程
详细设计目标
详细设计的目标:确定如何具体实现所要求的系统。
不是具体编写程序,而是设计程序的“蓝图”。
详细设计的结果决定最终程序代码的质量。
6.1 结构程序设计
结构程序设计
E.W.Dijkstra 最早提出结构程序设计:程序质量与程序中包含的Goto语句的数量成反比(1965)。
1966 ,Bohm, Jacopini ,证明了只用“顺序”、“选择”、“循环”控制结构就能实现任何单入口单出口程序。
理论上,最基本的控制结构只有两种:顺序、循环结构(选择结构可由其两者构造)。
学界认识到,不是简单去掉Goto语句的问题,而是要创立一种新的程序设计方法——结构化程序设计(IBM率先成功运用)。
结构程序设计:一种设计程序的技术,它采用自顶向下逐步求精的设计方法和单入口单出口的控制结构。
使用结构程序设计技术的好处
1)提高软件开发工程的成功率和生产率;
2)系统有清晰的层次结构,容易阅读理解;
3)单入口单出口的控制结构,容易诊断纠正;
4)模块化可以使得软件可以重用;
5)程序逻辑结构清晰,有利于程序正确性证明。
结构程序设计的类型
经典的结构程序设计:只允许使用顺序、IF_THEN_ELSE选择和DO_WHILE循环;
扩展的结构程序设计:除了三种基本控制结构,还使用DO_CASE和DO_UNTIL循环;
修正的结构程序设计:除了三种基本控制结构和两种扩充结构,还使用BREAK等结构。
结构化程序的结构
1. 三种结点
流程图通常由三种结点组成:
1)函数结点
如果一个结点有一个入口线和一个出口线,则称为函数结点。
由于函数结点一般对应于赋值语句,所以 F 也表示了这一个结点对应的函数关系。
2)谓词结点
如果一个结点有一个入口线和两个出口线,而且它不改变程序的数据项的值,则称为谓词结点。
P是一个谓词,根据P的逻辑值(T或F),结点有不同的出口。
3)汇点
如果一个结点有两个或多个入口线和一个出口线,而且它不执行任何运算,则称为汇点 。
2. 三种基本控制结构
1)顺序结构
相当于“A、B”
2)选择结构
相当于“If exp then A else B endif ”
3)循环结构
相当于“While exp do A”
3. 扩充两种控制结构
1)多分支结构
相当于“Case I of I=1:C1; I=2:C2; I=3:C3; … ; I=n:Cn”
2)UNTIL循环结构
相当于“Repeat A Until exp”
6.2 人机界面设计 ○
6.2.1 设计问题
- 系统响应时间;
- 用户帮助;
- 出错信息处理;
- 命令交互
6.2.2 设计过程
迭代过程(p121)
6.2.3 人机界面设计指南
- 一般交互指南;
- 信息显示指南;
- 数据输入指南。
6.3 过程设计的工具 ★
6.3.1 程序流程图 ★
程序流程图:是一种描述程序的控制结构流程和指令执行情况的有向图。历史悠久、使用广泛、直观描绘控制流程、便于初学者掌握。
ASP检索程序流程图:
程序流程图的缺点:
- 1)程序流程图本质上不是逐步求精的好工具,它诱使程序员过早地考虑程序的控制流程,而不去考虑程序的全局结构。
- 2)程序流程图中用箭头代表控制流,因此程序员不受任何约束,可以完全不顾结构程序设计的精神,随意转移控制。
- 3)程序流程图不易表示数据结构。
6.3.2 盒图(N-S图) ★
Nassi和Shneiderman提出了盒图,又称为N-S图。
盒图的特点有:
- 1)功能域明确,可以从盒图上一眼就看出来;
- 2)不可能任意转移控制;
- 3)很容易确定局部和全程数据的作用域;
- 4)很容易表现嵌套关系,也可以表示模块的层次结构。
盒图的例子:
6.3.3 PAD图
PAD(Problem Analysis Diagram)是问题分析图,日立公司发明和推广(1973)。
例子:
PAD图的优点:
- 1)使用表示结构化控制结构的PAD符号所设计出来的程序必然是结构化程序;
- 2)PAD图所描绘的程序结构十分清晰。图中最左面的竖线是程序的主线,即第一层结构。随着程序层次的增加,PAD图逐渐向右延伸,每增加一个层次,图形向右扩展一条竖线。PAD图中竖线的总条数就是程序的层次数;
- 3)用PAD图表现程序,通俗易懂,程序从图中最左竖线上端的结点开始执行,自上而下,从左向右顺序执行,遍历所有结点;
- 4)容易将PAD图转换成高级语言源程序,这种转换可以用软件工具自动完成;
- 5)可用于表示程序逻辑,也可用于描绘数据结构;
- 6)PAD图的符号支持自顶向下、逐步求精的方法。
6.3.4 判定表 ★
判定表由四部分组成:
- 左上部列出所有条件
- 左下部是所有可能做的动作
- 右上部表示各种条件组合
- 右下部是和每种条件组合相对应的动作
6.3.5 判定树 ★
判定树是判定表的变种。
6.3.6 过程设计语言(PDL)
PDL也称为伪码。
如:
if I>0 then
执行订单数据输入模块
else
报告出错信息
end if
PDL的优点:
- 1)可以作为注释直接插在源程序中间;
- 2)可以使用普通的正文编辑程序或文字处理系统来完成PDL的书写和编辑工作;
- 3)现在已经有一些自动处理程序可以自动地把PDL生成程序代码。
PDL的缺点:不如图形工具形象直观。
6.4 面向数据结构的设计方法 ★
6.4.1 Jackson图 ★
1)顺序结构
2)选择结构
3)重复结构
6.4.2 改进的Jackson图
6.4.3 Jackson方法
Jackson方法的目标是:得出对程序处理过程的详细描述。
步骤
Jackson结构程序设计方法由五个步骤组成:
1)分析并确定输入数据和输出数据的逻辑结构,并用Jackson图描绘这些数据结构;
2)找出输入数据结构和输出数据结构中有对应关系的数据单元;
3)用三条规则从描绘数据结构的Jackson图导出描绘程序结构的Jackson图:
- A.为每对有对应关系的数据单元,按照它们在数据结构图中的层次在程序结构图的相应层次画一个处理框;
- B.根据输入数据结构中剩余的每个数据单元所处的层次,在程序结构图的相应层次分别为它们画上对应的处理框;
- C.根据输出数据结构中剩余的每个数据单元所处的层次,在程序结构图的相应层次分别为它们画上对应的处理框;
4)列出所有操作和条件(包括分支条件和循环结束条件),并且把它们分配到程序结构图的适当位置;
5)用伪码表示程序。
伪码
与三种基本结构对应的伪码是:
顺序结构:
A seq
B
C
D
A end
选择结构
A select cond1
B
A or cond2
C
A or cond3
D
A end
重复结构
A iter until(或while) cond
B
A end
实例
例:一个正文文件由若干记录组成,每个记录是一个字符串。
如:
- Record 1:How many stages are there in the traditional software development model?
- Record 2: After entering the room, walk to the person sitting nearest to you and greet him/her with a “high five”.
- Record 3: What are encapsulated into an object?
- Record 4: What diagram is the following diagram? Simply describe the meaning of it.
要求:
- 1)设计程序统计每个记录中空格字符的个数,输出数据的格式是,每读入一个记录(字符串)之后,另起一行打印出这个字符串及其空格数;
- 2)最后打印出文件中空格的总个数。
分析输入、输出数据结构,用Jackson图描绘,并找出两者对应的数据单元:
导出描绘程序结构的Jackson图:
列出所有操作和条件:
(1)停止
(2)打开文件
(3)关闭文件
(4)印出字符串
(5)印出空格数目
(6)印出空格总数
(7)sum := sum +1
(8)totalsum := totalsum + sum
(9)读入字符串
(10)sum := 0
(11)totalsum : = 0
(12)pointer := 1
(13)pointer := pointer + 1
I(1) 文件结束
I(2) 字符串结束
S(3) 字符是空格
6.5 程序复杂度的定量度量
定量度量程序复杂度的作用:
- (1)可估算软件中错误的数量及软件开发工作量;
- (2)度量的结果可用来比较不同设计或不同算法的优劣;
- (3)程序的复杂度可作为模块规模的限度。
6.5.1 McCabe(麦凯布)方法 ★
1. 流图
“退化”的程序流程图,仅描绘程序的控制流程,不表现对数据的具体操作及循环、选择的条件。
复合条件:包含了一个或多个布尔运算符(OR、AND、NOR等)。
应把复合条件分解为简单条件,每个条件对应一个结点。
2. 计算环形复杂度的方法
1)环形复杂度 V(G)等于流图中的区域数;
2)环形复杂度 V(G)=E-N+2,其中E是流图中边的条数,N是结点数;
3)环形复杂度 V(G)=P+1,其中P为流图中判定结点的数目。
例:计算下列程序图的程序复杂度
解:
方法一:程序图把平面分为4个区域,程序复杂度V(G)=4;
方法二:边的条数E=11,结点数N=9,程序复杂度V(G)=E-N+2=4 ;
方法三:判定结点为1、2、4点,数目为P=3个,所以V(G)=P+1=4。
3. 环形复杂度的用途
对测试难度的一种定量度量,也能对软件最终的可靠性给出某种预测。
实践表明,模块规模以V(G)≤10为宜。
6.5.2 Halstead(霍尔斯特德)方法
根据程序中运算符和操作数的总数来度量程序复杂度:N = N1 + N2
- 其中:N定义为程序长度;
- N1为程序中运算符出现的总次数;
- N2为操作数出现的总次数。
Halstead给出预测程序长度的公式为:H = n1log2n1 + n2log2n2
- 其中:H定义为程序预测长度;
- n1为程序中使用的不同运算符(包括关键字)的个数;
- n2为程序中使用的不同操作数(变量和常量)的个数。
多次验证都表明,程序的预测长度H和实际程序长度N非常接近。
Halstead还给出了预测程序中包含错误的个数的公式:E = N log2(n1+n2) / 3000
小结
◇ 详细设计说明书
着重描述每一模块是怎样实现的,包括实现算法、逻辑流程等。
重点
环形复杂度的计算,三种计算方法
程序流程图与NS图的互相转化
判定表和判定树
面向数据结构的Jackson图