正文
4. 面向数据结构的设计方法
4.1. 面向数据结构的设计方法概述
数据结构既影响程序的结构又影响程序的处理过程,最终目标是得出对程序处理过程的描述,一般来说这种设计方法有着以下三条设计准则:
重复出现的数据通常由具有循环控制结构的程序来处理;
选择数据要用带有分支控制结构的程序来处理;
层次的数据组织通常和使用这些数据的程序的层次结构相似。
这里我们介绍一下Jackson结构程序设计方法,它是一种结构化编程方法,以数据流结构及程序结构之间的对应关系为基础。Jackson方法将程序及数据用顺序、选择、循环结构的组合来表示,适合用来设计程序的细部控制结构。
4.2. Jackson图
数据结构中数据元素彼此间的逻辑关系有三种:
顺序结构:顺序结构的数据由一个或多个数据元素组成,每个元素按确定次序出现一次;
选择结构:选择结构的数据包含两个或多个数据元素,每次使用这个数据时按一定条件从这些数据元素中选择一个;
循环结构:重复结构的数据,根据使用时的条件由一个数据元素出现零次或多次构成。
Jackson图形象直观可读性好,便于表示层次结构,而且是对结构进行自顶向下分解的有力工具,它既能表示数据结构也能表示程序结构。但当用Jackson图表示选择或重复结构时,选择条件或循环结束条件不能直接在图上表示出来,影响了图的表达能力,也不易直接把图翻译成程序,另一方面,Jackson图的框间连线为斜线,不易在行式打印机上输出。
4.4. Jackson方法
Jackson结构程序设计方法由5个步骤组成:
分析并确定输入数据和输出数据的逻辑结构,用Jackson图描绘数据结构;
找出输入数据结构和输出数据结构中有对应关系的数据单元。
所谓有对应关系是指有直接的因果关系,在程序中可以同时处理的数据单元(对于重复出现的数据单元必须重复的次序和次数都相同才可能有对应关系)。
用下述规则从描绘数据结构的Jackson图导出描绘程序结构的Jackson图:
第一,为每对有对应关系的数据单元,按照它们在数据结构图中的层次在程序结构图的相应层次画一个处理框(层次不同时与图中层次低的那个对应);
第二,根据输入数据结构中剩余的每个数据单元所处的层次,在程序结构图的相应层次分别为它们画上对应的处理框;
第三,根据输出数据结构中剩余的每个数据单元所处的层次,在程序结构图的相应层次分别为它们画上对应的处理框。
改进的Jackson图规定在构成顺序结构的元素中不能有重复出现或选择出现的元素,因此可能需要增加中间层次的处理框。
列出所有操作和条件(包括分支条件和循环结束条件),并且把它们分配到程序结构图的适当位置。
用伪码表示程序。
例如:假设一个文件由若干个记录组成,每个记录是一个字符串。要求统计每个记录中空格字符的个数,以及文件中空格字符的总个数。要求的输出数据格式是,每复制一行输入字符串之后,另起一行印出这个字符串中的空格数,最后印出文件中空格的总个数。
用 Jackson结构程序设计方法的设计步骤如下:
用Jackson图描绘的输入输出数据结构
分析确定在输入数据结构和输出数据结构中有对应关系的数据单元
从数据结构图导出程序结构图
列出所有操作和条件,并且把它们分配到程序结构图的适当位置
- 用伪码表示程序处理过程
5. 程序复杂程度的定量度量
5.1. 程序复杂程度的定量度量概述
详细设计阶段设计出的模块质量可以使用软件设计的基本原理和概念进一步仔细衡量它们的质量。但是,这种衡量毕竟只能是定性的,人们希望能进一步定量度量软件的性质。
定量度量程序复杂程度可以把程序的复杂程度乘以适当常数即可估算出软件中错误的数量以及软件开发需要用的工作量,定量度量的结果可以用来比较两个不同的设计或两个不同算法的优劣,也可以作为模块规模的精确限度。
5.2. McCabe方法
McCabe方法是一种软件质量度量方法,它是基于对程序拓扑结构复杂度的分析。 它根据程序控制流的复杂程度定量度量程序的复杂程度,这样度量出的结果称为程序的环形复杂度。
它的表示是一张流图,所谓流图实质上是简化的程序流程图,它仅仅描绘程序的控制流程,完全不表现对数据的具体操作以及分支或循环的具体条件。
流图的表示图符:
结点:用圆表示,一个圆代表一条或多条语句;
边:箭头线称为边,代表控制流。在流图中一条边必须终止于一个结点,即使这个结点并不代表任何语句;
区域:由边和结点围成的面积称为区域,包括图外部未被围起来的区域。
如下图所示:
任何方法表示的过程设计结果,都可以翻译成流图,在流图中,对不同结构有不同的表示方法,例如:
- 对于顺序结构,一个顺序处理序列和下一个选择或循环的开始语句,可以映射成流图中的一个结点
对于选择结构,开始语句映射成一个结点;两条分支至少各映射成一个结点;结束映射成一个结点
对于循环结构,开始和结束语句各映射成一个结点。
- 当过程设计中包含复合条件时,应该把复合条件分解为若干个简单条件,每个简单条件对应流图中一个结点。所谓复合条件,就是在条件中包含了一个或多个布尔运算符(逻辑OR,AND,NAND,NOR)。
例如:
计算环形复杂度的方法
环形复杂度定量度量程序内分支数或循环个数,即程序结构的复杂程度,它可以定量地度量测试难度,然后能对软件最终的可靠性给出某种预测。大量实践表明,模块环形复杂度以V(G)≤10为宜。
环形复杂度定量度量程序的逻辑复杂度。有了描绘程序控制流的流图之后,可以用下述3种方法中的任何一种来计算环形复杂度V(G):
V(G)=流图中的区域数;
V(G)=E-N+2(其中E是流图中的边数,N是结点数)
V(G)=P+1(其中P是流图中判定结点的数目 )
5.3. Halstead方法
Halstead方法根据程序中运算符和操作数的总数来度量程序的复杂程度。
令N 1 为程序中运算符出现的总次数,N 2 为操作数出现的总次数,程序长度N NN定义为:N = N 1 + N 2 N程序中使用的不同运算符(包括关键字)的个数n 1 ,以及不同操作数(变量和常数)的个数n 2。预测程序长度的公式如下:
预测程序中包含错误的个数的公式如下: