面向对象软件度量因子的幂律分布研究

2018-02-27 03:09冼伟成刘宏韬胡志刚
计算机应用与软件 2018年1期
关键词:面向对象度量代码

冼伟成 刘 伟,2 刘宏韬 胡志刚

1(中南大学软件学院 湖南 长沙 410075) 2(湖南中医药大学管理与信息工程学院 湖南 长沙 410208)

0 引 言

幂律分布相关理论研究在自然语言处理和各种自然数据分析中已经取得较丰硕的成果。众所周知的8020法则就是幂律分布的一种典型表现形式。在一次软件工程会议上,人们通过研究发现“软件工程研究中,80%的贡献来自于20%的科研人员”[1],这就是幂律分布存在于软件工程领域中的一种宏观表现。如今,在软件质量领域的经验研究中,研究度量结果中出现的幂律分布特征是其中的一个重要方向。

研究软件中幂律分布的存在形式,并分析其产生原因,可以从经验研究的角度为软件质量研究提供依据,有助于软件工程研究人员深入理解影响代码质量的原因。在软件开发过程中结合幂律分布规律指导开发,有利于提高软件的可靠性、可维护性,在提升代码质量的同时提高开发效率。

本文主要对4个大型Java开源项目进行研究,分别对影响软件质量的3个主要度量因子进行度量。利用幂律分布的研究方法对3个度量因子的分布规律进行研究。本文采用极大似然估计法MLE(Maximum Likelihood Estimate)分别求得各个项目度量因子统计结果的拟合形状参数,并使用假设检验对幂律分布的拟合效果进行评价。利用度量因子统计结果拟合的幂律分布函数,在4个大型Java开源项目中发现潜在软件质量问题。

1 幂律分布在软件系统中的研究背景

1.1 幂律分布概述

在大多数关于幂律分布的研究中,将幂律分布分为两类进行单独研究:离散型和连续型。

连续型幂律分布的概率密度函数PDF(Probability Density Function):

(1)

当α>1和xmin>0时,离散型幂律分布的概率质量函数PMF(Probability Mass Function):

(2)

(3)

式(3)是推广的zeta函数。且当xmin=1时,ζ(α,1)是标准的zeta函数。

幂律分布的累积分布函数有非常简单的形式,对于连续型幂律分布的累积分布函数为:

(4)

(5)

1.2 基于极大似然估计的幂律分布拟合法

在已有关于面向对象软件度量中幂律分布研究的文献中,绝大部分使用在双对数坐标系中采用线性拟合来获得幂律分布的形状参数。这种方法是拟合幂律分布函数最常用的方法,但这种方法存在较大的主观性且容易出错。Clauset在文献[2]中对比了三种幂律分布函数的拟合方式,文中发现拟合效果最差的方法是采用双对数坐标系中线性拟合的方式,而采用极大似然估计法获得幂律分布函数的形状参数是最可靠的方法。

形状参数可以通过极大似然估计法直接求得,对于连续型幂律分布:

(7)

(8)

离散型幂律分布函数形状参数α值的极大似然估计与连续型幂律函数形状参数α值近似。

在使用极大似然估计法计算形状参数α的时候,需要以一个特定的xmin值作为参数。因此需要事先求出xmin值才能确定形状参数α。文献研究表明,大部分实际数据中只有数据的尾部才符合幂律分布情况,随着xmin值的增长,实验中被抛弃的数据也越来越多。为了使拟合函数能覆盖大部分数据,选择xmin值时需要慎重考虑。

为了精确找到xmin值,本文没有采用操作方式简单但容易出现误差的双对数坐标图法。而采用了Clauset提出的一种基于柯尔莫哥洛夫-斯米尔诺夫检验(Kolmogorov-Smirnov test,K-S检验)的xmin值预测方法[2]。这种方式将所有x的取值进行遍历,将每次所取的x值作为xmin,然后找到大于或等于xmin值时实际数据和拟合分布函数的累计分布函数CDF(Cumulative Distribution Function)值间差的绝对值最大的情况,并将最大值作为此次遍历的D值。遍历结束后找到使D值最小的x作为xmin值。

(9)

S(x)和P(x)分别为实际数据和拟合函数的CDF值(x≥xmin)。这种方法同时适用于对数正态分布和幂律分布的xmin值预测。

1.3 分布函数拟合优度检验方法

在目前的幂律分布相关研究中,有关形状参数估计的研究没有考虑检验假设与实际数据的拟合程度。因此,其估计结果并不严格。为了验证通过极大似然估计方式获取的形状参数是否适用于实际数据,需要采用假设检验来对分布函数进行检验。有两种常用的分布函数拟合优度检验,一种是Pearson卡方检验,另一种是K-S检验。虽然Pearson卡方检验比较容易实现,但是检验的可靠性比较差。最终选择K-S检验来对实验结果是否满足幂率分布的情况进行检验。

K-S检验是建立在以下公式:

K=supx|F*(x)-S(x)|

(10)

式中:F*(x)代表预先假设的理论分布函数,S(x)代表样本的累计概率分布函数。K-S检验统计量的大小反映了假设分布与经验分布的拟合程度。

本文对幂律分布和对数正态分布的拟合优度检验,引入K-S检验统计量,结合Clauset等提出了一种基于拔靴法的适用于幂律分布函数和其他拟合函数的拟合优度检验方法[2],来验证上文拟合方法获得的形状参数的估计效果。该方法使用P值来量化假设的合理性,从而在一定程度上提供对估计结果可信度的判断。如果P值大于0.1,则实际数据与理论模型产生数据之间的差值可以被解释为统计波动。如果P值接近0,则说明理论模型不能较好地拟合实际数据,需要使用其他模型来描述实际数据。当对幂律分布函数进行假设检验时的假设为:

H0:实际数据产生于幂律分布函数

H1:实际数据并非产生于幂律分布函数

基于拔靴法的幂律分布假设检验算法如下所示:

幂律分布假设检验算法

1 Calculate point estimates forxminand the scaling parameterα

2 Calculate the Kolmogorov-Smirnov statistic,KSd, for the original data set.

3 Setn1equal to the number of values belowxmin.

4 Setn2=n-n1andP=0.

5 for i in 1:B:

6 Simulaten1values from a uniform distribution: U(1,xmin) andn2values from a power law distribution (with parameterα).

7 Calculate the associated Kolmogorov-Smirnov statistic,KSsim.

8 IfKSd>KSsim,thenP+P+1.

9 end for

10P=P/B.

1.4 幂律分布在软件系统中的研究

软件工程领域的研究者也将幂律分布运用于面向对象软件相关复杂网络的研究中。随着面向对象软件大小的增加,研究人员发现,在某些层次中实体间的关系可以用无标度网络来进行研究,例如代码行数、方法调用数和圈复杂度等。已经有研究者在软件系统中发现了幂律分布的存在。

马皖王莹等将复杂网络的特征度量用于缺陷的预测研究中,发现JEdit软件的源代码网络特征度量符合幂律分布[3]。韩明畅等将复杂网络理论引入人工设计和实现的软件中, 把其中的实体和关系转换成为网络拓扑的形式,发现Java类库中存在的无尺度特征、小世界现象和脆弱性鲁棒性并存的特点[4]。Valverde的研究,使用无标度网络图和幂律分布来研究Java和C/C++开源项目中软件的架构情况[5-6],将类作为节点,类间关系作为连线,发现节点的入度和出度分布情况符合幂律分布。Louridas等[7]将之前的工作进行总结,发现长尾分布广泛存在于面向对象软件的各个层次结构中,并指出了幂律分布和其他长尾分布在软件工程中的研究方向。需要指出的是,以上的研究主要使用在双对数坐标系中采用线性拟合来获得幂律分布的形状参数,有可能会造成较大误差。

2 幂律分布在面向对象软件度量中的应用

将幂律分布在自然语言处理和各种复杂网络分析中的研究方法适当改进,运用于在不同层次软件结构中的面向对象软件度量。验证幂律分布在面向对象软件度量中的存在,并解释幂律分布出现的原因,利用拟合的幂律函数对软件质量改进提供指导。为了减小拟合误差,本文采用极大似然估计方法获得幂律分布形状参数α,并使用基于K-S检验的拟合优度检验法检验拟合效果。

2.1 实验准备

本实验采用的数据集来自Qualitas Corpus项目[8],它是由奥克兰大学的Ewan Tempero教授收集整理的软件系统代码集。项目的目的是为软件工程经验研究提供一个可重复研究的资源。截至到2013年9月,Qualitas Corpus已经收集了112个具有代表性的Java软件系统,其中包括著名的Eclipse和NetBeans等。我们选取了其中最具有代表性的4个大型开源项目进行研究,包括Java集成开发环境Eclipse、NetBeans,Java运行时环境JRE(Java Runtime Environment),还有分布式系统基础架构Hadoop。项目说明如表1所示。

表1 实验项目简要说明

本文使用研究小组开发的开源代码度量工具Perfume[9]对已收集的4个Java开源项目进行度量。Perfume是一款基于抽象语法树AST(Abstract Syntax Tree)的代码度量工具。利用AST将源代码对应结构处理成树状结构,极大提高代码度量效率。在AST的处理中,将每个Java文件定义为一个编译单元(Compilation Unit),一个编译单元中可以存在多个类定义。为了精确获得每个类的度量值,使用AST中定义的类声明节点(TypeDeclaration)作为类的区分标准。所有针对类的度量值都是针对类申明节点的度量。Perfume工具支持对28种常见的代码度量项目进行度量,其中包括经典CK度量集等。实验选取了3个经典度量因子,如表2所示。

表2 度量因子简要说明

本文中度量结果的统计分析和幂律函数的拟合与假设检验,使用Gillespie等编写的 R语言函数包——PoweRlaw包[10]进行相关处理。

2.2 实验方案

本文在面向对象软件度量中的幂律分布研究过程如下,流程图如图1所示。

图1 幂律分布在面向对象软件度量中的实验流程图

第一步在Qualitas Corpus官方网站上下载需要研究的Java开源项目的源代码。并对源代码文件进行预处理,将测试用例文件中会对度量产生影响的源代码文件删除。

第二步确定需要研究的面向对象度量因子,使用软件度量工具Perfume对4个开源项目进行度量。将获得的度量值进行预处理。对于LOC、NOA和NOM3个度量因子,将度量结果值为0的类剔除,仅保留度量值大于0的类。

第三步使用基于K-S检验的xmin值预测方法获得xmin值,利用极大似然估计法求得在xmin值下的幂律函数形状参数α。使用Clauset等提出的拟合优度检验方法对获得的幂律函数的拟合效果进行检验。

第四步对于拟合效果较好的度量值进行研究,研究幂律分布在相应度量因子中产生的原因。并利用拟合后的幂律函数找到不符合分布规律的类,研究其对软件质量的影响。

3 度量因子的幂律分布研究结果与分析

本节中,主要对4个具有代表性的大型Java开源项目的面向对象软件度量值进行统计与分析。我们对以上开源项目的3个经典度量因子进行度量统计,从统计值中找到一些统计学规律。表3展示了一些对于以上开源项目的描述统计结果。

表3 实验项目描述统计

3.1 类代码行数

代码行数是评价软件质量的基础性度量因子,用于度量软件的大小。本文中度量的代码行数为类代码行数,但不包括注释语句和空白行。从描述统计结果表3中可以发现,4个项目的LOC平均值比较接近,均在130左右。而JRE项目的中位数为36,其他3个项目均在50以上。而且JRE项目中LOC的最大值6 787也远小于其他项目。这可能与项目的类型有关。从偏度值看出,均存在长尾情况。为了更加清晰地观察4个项目LOC统计结果的分布情况,使用互补累计分布函数CCDF(Complementary Cumulative Distribution Function)图来描述实际数据和拟合情况,如图2所示。由于幂律分布主要出现在数据的尾部,可以发现拟合的幂律分布的xmin值都比较大,这意味着有大量的数据被抛弃,会在一定程度上影响拟合结果的可靠性,故使用K-S检验来验证。详细拟合结果和假设检验结果如表4所示。可以从表中看出,除了JRE项目以外,其余项目可以较好地拟合对数正态分布情况。这与Concas等的研究一致[11]。在数据尾部的拟合中,发现其中3个项目均有幂律分布情况存在。Eclipse和Hadoop项目尾部拟合幂律分布函数的形状参数α值在3.0左右。而在JRE项目中,尾部拟合幂律分布函数的形状参数α为4.5,远高于其他项目。在Netbeans项目中没有在尾部发现明显的幂律分布情况。但可以从图中发现,其尾部数据呈现明显不规则情况,意味着存在较多代码行数偏高的类。

图2 LOC度量值互补累计分布函数图

图2中,虚线代表使用对数正态分布函数拟合的结果,实线代表幂律分布函数拟合的结果,Xmin_in代表拟合对数正态分布的xmin值,Xmin_pl代表拟合幂律分布的xmin值。

表4 LOC度量值拟合结果

将偏离拟合函数较多的类单独进行分析,发现这些类均在拟合函数右侧,意味着代码行数过多。对于NetBeans项目来说,偏离拟合函数最多的类的全限定名为org.netbeans.modules.css.lib.Css3Parser,总共代码行数为36 731行。该类的主要功能是解析Css3文件内容,包含有大量的条件语句,类圈复杂度更是达到了7 712。这个类职责过重,将导致系统后期可维护性降低。

从累计分布中可以发现,在Eclipse、JRE和Hadoop项目中80%的类代码均小于160行,而NetBeans项目明显高于其他3个项目,达到了200行。在一个优秀的面向对象软件设计中,设计人员会使用大量的继承和关联特性,从而达到复用的目的。合理的复用代码可以降低系统复杂程度,并减少代码行数。

3.2 类方法属性个数

类方法属性个数,代表每个类中属性值的个数。从表3中可以发现,4个项目方法属性个数中位数均为3,且存在较明显的长尾分布情况。在最大值方面,Eclipse和NetBeans两个编译器的最大值均在2 000以上,远高于JRE和Hadoop项目的最大值。在Eclipse项目中,最高值2 042存在于一个核心功能类中,全限定名为org.eclipse.swt.internal.win32.OS,用于兼容各种版本Windows操作系统外观。而在NetBeans项目中,最高值2 021在全限定名为org.netbeans.modules.css.lib. Css3Parser的类中,这个类在LOC的度量中也是最高的。从表5中可以发现,4个项目均比较好地拟合幂律分布函数。在对数正态分布函数的拟合中,除了Eclipse项目外其他3个项目均得到很好的效果。在Eclipse和JRE两个项目中,尾部拟合的幂律分布函数形状参数α在2.25到2.46之间,而在NetBeans和Hadoop项目中,尾部拟合幂律分部函数的形状参数α在3.37到3.40之间。观察图3可以发现,在4个项目中均有偏离拟合函数较大的点存在,这些点的值往往大大高于平均值。在Hadoop项目中,偏离拟合函数最多的3个类为DFSConfigKeys、YarnConfiguration、CommonConfigurationKeysPublic,3个类中类属性个数为586、423和116。这些类均是用于保存Hadoop中的配置常量的。可以很明显地发现,这些用于存储配置常量的类均不是我们面向对象中传统意义的类,可以使用其他方式将属性值单独存储。

图3 NOA度量值互补累计分布函数图

项目名称拟合分布参数参数值xmin覆盖类数P值Eclispepowerlawlog-normalαμσ2.4554320.6054261.4011551122150119650.170.00Hadooppowerlawlog-normalαμσ3.3944230.4824171.2730203135621210.810.61JREpowerlawlog-normalαμσ2.2576331.3484051.47515520143645330.260.47NetBeanspowerlawlog-normalαμσ3.3774600.9520821.075416281631309130.690.13

3.3 类方法个数

类方法个数是指一个类中所包含的全部方法的个数,但不包含内部类和匿名类中的方法。这是一种CK度量集中的因子,可用于对大型软件的质量和缺陷进行预测。在表3中可以发现,被统计项目的偏度值明显偏高,说明存在长尾分布的特点。为了研究类方法个数的分布情况,使用对数正态分布和幂律分布对数据进行了函数拟合。拟合结果如表6所示,这4个Java大型开源项目的类方法个数统计值在尾部均呈现幂律分布,其中Hadoop项目符合幂律分布的数据量最多,共有占全部统计值的42.7%。而其余3个项目只有4%左右的数据符合。在尾部幂律分布中,形状参数α在3.28到3.48之间。

表6 NOM度量值拟合结果

图4展示了实际数据的累积分布函数。在累计分布函数图上,4个大型Java开源项目在图像上可获得看似较好的拟合结果。为了验证两种拟合函数的拟合效果,使用K-S检验分别对拟合函数进行检验。从K-S检验结果可以看出,这4个Java开源项目的类方法个数统计结果均在尾部均发现了幂律分布。虽然在图形上看起来对数正态分布的拟合曲线拟合的情况较好,但通过K-S检验我们可以发现,只有在Hadoop项目中发现了较明显的对数正态分布情况,其他3个项目均未通过检验。

图4 NOM度量值互补累计分布函数图

对于一个面向对象程序来说,类方法数量越多代表类的职责越重,会导致该类与其他类间过高的耦合度,从而影响代码质量。可以从累计分布图中发现,4个项目中80%的类中均少于12个方法。Eclipse、Hadoop和NetBeans项目中99%的类方法个数小于60,

而JRE项目中这个值达到了74。这可能和软件类型有关系,JRE比起一般应用程序来说,它作为Java语言的API需要向外部提供了更多的入口,也就是公共方法。通过观察图4可以发现,JRE项目中存在较多方法数量过高的类。查看具体类发现,JRE中方法数排名前5的类中,有3个是用于封装异常处理方法的类,且都来自包com.sun.corba.se.impl.logging。值最高的类ORBUtilSystemException中方法数达到1 259个。而在NetBeans项目中,值最高的类含有406个方法,类全限定名为org.netbeans.lib.ddl.adaptors.DefaultAdaptor,类的功能是数据库适配器。过多的方法会导致代码味道的产生,也会影响软件的复用和可维护性。

4 结 语

以上研究中发现,在4个大型Java开源项目的面向对象软件度量中,绝大多数类度量因子的值处在一个较低的水平,而只有极少数类的度量因子的值相当大,属于典型的长尾分布特征。经过相关拟合与假设检验,发现在4个项目中,幂律分布是产生长尾现象的原因之一。软件开发作为一种智慧密集型工作,存在大量人为因素从而影响软件开发过程,所以不能用一个统一的模型来描述不同软件的度量因子统计结果。甚至有些项目无法找到一个合理的模型来描述。但是在同一个软件开发过程中,开发人员总是按照相同的设计框架进行开发,这在一定程度上确定了各种代码度量因子的增长模型。在对度量统计结果拟合幂律分布函数后,如发现有偏离拟合函数较大的度量结果出现,基本可以判断是存在不符合本项目设计框架的代码出现。例如在NetBeans项目中的Css3Parser类,LOC和NOA的度量值都极大偏离拟合的幂律函数,这说明Css3Parser类的设计不符合面向对象软件设计要求。

长尾现象不管是由幂律分布产生,还是由对数正态分布产生,或是其他的分布函数产生。长尾现象对软件工程来说,都是一个值得进行研究的课题。因为长尾现象的存在说明少数的类在软件开发中起到重要作用,而这些类的代码质量直接决定了软件的可靠性和可维护性。在开发中提高这些类质量,有利于软件整体质量的提高。

[1] Boehm B.Industrial Software Metrics Top 10 List[J].IEEE Software,1987,4:84-85.

[2] Clauset A,Shalizi C R,Newman M E J.Power-Law Distributions in Empirical Data[J].Siam Review,2014,51(4):661-703.

[3] 马皖王莹,陈林,陈芝菲,等.基于复杂网络分析的软件高危缺陷评估方法[J].计算机科学与探索,2014,8(8):956-965.

[4] 韩明畅,李德毅,刘常昱,等.软件中的网络化特征及其对软件质量的贡献[J].计算机工程与应用,2006,42(20):29-31.

[5] Valverde S,Sole R V.Hierarchical Small Worlds in Software Architecture[J].Dynamics of Continuous Discrete & Impulsive Systems,2007,14.

[6] Valverde S,Cancho R F I,Sole R V.Scale-free Networks from Optimal Design[J].Epl,2002,60(4):512-517.

[7] Louridas P,Spinellis D,Vlachos V.Power Laws in Software[J].ACM Transactions on Software Engineering & Methodology,2008,18(1):617-632.

[8] Tempero E,Anslow C,Dietrich J,et al.The Qualitas Corpus:A Curated Collection of Java Code for Empirical Studies[C]//Asia Pacific Software Engineering Conference.IEEE Computer Society,2010:336-345.

[9] Liu Hongtao.Perfume:A code quality assessment platform based on machine learning[EB/OL].https://github.com/LiuHongtao/Perfume.

[10] Gillespie C S.Fitting Heavy Tailed Distributions:The poweRlaw Package[J].Journal of Statistical Software,2015,64(2).

[11] Concas G,Marchesi M,Pinna S,et al.Power-Laws in a Large Object-Oriented Software System[J].IEEE Transactions on Software Engineering,2007,33(10):687-708.

猜你喜欢
面向对象度量代码
GEE平台下利用物候特征进行面向对象的水稻种植分布提取
鲍文慧《度量空间之一》
代数群上由模糊(拟)伪度量诱导的拓扑
面向对象方法在水蓄冷PLC编程中应用分析
突出知识本质 关注知识结构提升思维能力
面向对象的组合软件工程研究
度 量
创世代码
创世代码
创世代码