软件的复杂性度量方法概述

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

2.软件的复杂性度量方法概述

根据软件的生命周期,Halstead复杂性度量和McCabe圈复杂度度量都属于可以应用在软件测试阶段的度量技术。

在基于程序体积的复杂性度量算法中,最具影响力的是20世纪70年代由Halstead提出的软件科学度量理论[2]。Halstead从统计学和心理学的角度研究软件复杂性,把程序看成由可执行的代码行词汇(操作符和操作数)组成的符号序列。Halstead在其度量理论中采用一些基本的度量值来确定软件开发中的一些定量规律,这些度量值通常在程序产生之后得出,或者设计完成之后算出。Halstead的重要结论之一是:程序实际的Halstead长度值N可以由代码行词汇n算出。

McCabe于1976年指出:应该用程序流图的圈数(Cycloramic number)来测量程序的复杂性,并基于程序控制论和图论提出了经典的McCabe圈复杂性度量理论。McCabe控制流图是一种简化的程序流程图,如果把流程图中的每个基本框抽象为一个点,略去每个框的具体信息,就产生一个由结点和弧(或称为分支)组成的图,称为控制流图。控制流图是有向图,可用G = 表示,其中V 表示结点集合,代表程序流程图中的基本框;E表示有向边,代表程序流程图中的控制方向。图1则表示了一个典型程序及其相应的流程图:

A:InPut(Seore);

B:If Seore<45

C:Then Print(‘Fail,)

D:Else Print(‘Pass’)

E:If Seoer>80

F:Then Print(‘withdistinetion’)

G:End

图1 程序及其流程图

为了讨论的方便,以下给出图论中的几个术语定义:

强连通图:在有向图G中,任意两个结点x和y,都有一条从x到y的路径,反之亦然。

回路:指开始和终止于相同结点的路径。

圈:指一个回路,其中所有结点(不包括开始结点)最多只出现一次。

线性独立集:如果在一个集合中,任何一条路经都不是其他路径的线性组合,则称该集合为线性独立集。

圈的基集:即圈的最大线性独立集。在含有e条边和n个结点的图中,基集有e – n + 1个圈。

如果能够合理的编写程序,则总能够使控制流图中存在从开始结点(如图1中的结点A)到达图中的其他每个结点的路径。一般来说,控制流图不是强连通的,因为不可能从其较低的一些结点到达较高的一些结点,但是,如果程序结构中有一个包含整个程序的外循环,则存在一条从其中任意结点到开始结点的“出口→入口”弧(如图1中的弧GA),该弧使控制流图变成强连通的,因为:①从开始结点能够到达程序图中的任意结点;②从任意结点经“出口→入口”弧均可回到开始结点。

McCabe的圈复杂性度量就是考虑控制流图的圈的基集,因为在原始流图中加了一条边,所以对于一个流图为G的程序模块,如果G有e条边和n个结点,那么该程序模块的圈复杂度为:v(G) = e - n + 2。更简单地说,设d是G中的判定结点数,则v(G) = d + l。

软件工程的实践人员和研究人员一致认为:模块的圈数,即模块复杂度,与模块中所存在的软件错误数或缺陷数,以及为了发现并改正它们所需的时间之间存在着明显的联系。McCabe曾经指出:根据以往的经验,当一个模块的v超过10时,这个模块可能就会出问题。Grady和他的研究小组关于v的结论是:模块

中允许的最大圈数为15(Grady,1994)。Channel Tunnel铁路系统中的软件质量保证规格要求:如果模块的圈数超过20,则该模块不合格。

目前已提出的各种复杂性度量算法中,在软件工程界运用得比较多的是McCabe 的环计数和Halstead的软件科学度量法,我们称其为McCabe度量法和Halstead 度量法。下面我们将连同最古老的代码行数度量法一起分别对它们进行简单介绍。

代码行数度量法

代码行数度量法以程序的总代码行数作为程序复杂性的度量值。这种度量方法有一个重要的隐含假定是:书写错误和语法错误在全部错误中占主导地位。然而,由于这类错误严格来讲是私有的,不应把它们计入错误总数之中,在这种情况下,这种度量方法的前提就不存在。因而,代码行数度量法是一种很粗糙的方法,在实际应用中很少使用。

McCabe度量法

McCabe度量法以程序流程图的分析为基础,通过计算强连通的程序图中线性无关有向环的个数,建立复杂性的度量。其计算公式为:V(G)=m-n+p,其中V(G)是强连通有向图G中的环数;m是G中的弧数;n是G中的节点数;p是G 中分离部分的数目。

对于一个正常的程序来说,程序图总是连通的,即p=1。为了使之强连通,我们可以从出口点到入口点画一条虚弧。实际上,我们常常采用另一种计算方法来获得McCabe度量值,即对于单入口单出口模块(通常都属这种情况),我们只需计算程序中判断语句个数加1即可得V(G)值。McCabe度量法实质上是对程序控制流复杂性的度量,它并不考虑数据流,因而其科学性和严密性具有一定的局限性。

Halstead度量法

Halstead度量法通过计算程序中的运算符和操作数的数量对程序的复杂性加以度量。设n1表示程序中不同运算符的个数,n2表示程序中不同操作数的个数,N1表示程序中实际运算符的总数,N2表示程序中实际操作数的总数。令H 表示程序的预测长度,Halstead给出H的计算公式为:H=n1log2n1+n2log2n2;令N表示实际的程序长度,其定义为:N=N1+N2。Halstead的重要结论之一是:程序的实际长度N与预测长度非常接近。这表明即使程序还未编写完也能预先估算出程序的实际长度N。Halstead还给出了另外一些计算公式,包括:程序容量:V=N log2(n1+n2),程序级别:L=(2/n1) * (n2/N2),编制程序所用的工作量:E Λ=V/L,程序中的错误数预测值:B=N log2(n1+n2)/3000。

Halstead度量实际上只考虑了程序的数据流而没有考虑程序的控制流,因而也不能从根本上反映程序的复杂性。

需要说明一点的是,上述度量方法都是针对传统的结构化程序设计方法的。当将其应用到面向对象程序设计方法时,不再适用于其中的某些概念,如类、继承、封装和消息传递等。但在目前尚未找到专门针对面向对象的复杂性度量方法的情况下,这些传统的度量算法也能在一定程度上反映软件开发的复杂程度。

相关文档
最新文档