上帝类(God class)是指同时包含多种任务职责的类,其常见特征是包含大量的属性与方法,并且与系统中的其他类有多种依赖关系.上帝类是一种典型的代码坏味,对软件的开发维护产生负面影响.近年来,许多研究都致力于发现和重构上帝类,但是现有方法识别上帝类的能力不强,检测精确率不高.提出了一种基于图模型和孤立森林的上帝类检测方法,主要分为两个阶段:图结构信息分析阶段和类内度量评估阶段.在图结构信息分析阶段,建立类间的方法调用图和类内结构图,采用孤立森林算法缩小上帝类的检测范围;在类内度量评估阶段,考虑项目的规模和架构带来的影响,将项目中上帝类相关度量指标的平均值作为基准,设计实验确定比例因子,并以平均值和比例因子的乘积作为阈值,筛选得到上帝类的检测结果.在代码坏味标准数据集上的实验结果表明:与现有的上帝类检测方法相比,该方法在精确率和
God class refers to a class that carries heavy tasks and responsibilities. The common feature of God class is that it contains a large number of attributes and methods, and has multiple dependencies with other classes in the system. God class is a typical code smell, which has a negative impact on the development and maintenance of the software. In recent years, many studies have been devoted to discovering or refactoring the God class; however, the detection ability of existing methods is not strong, and the detection precision is not high enough. This study proposes a God class detection approach based on graph model and isolation forest algorithm, which can be divided into two stages: The stage of the graph structure information analysis and the stage of intra-class measurement evaluation. In the stage of the graph structure information analysis, inter-class method call graphs and intra-class structure graphs are established, respectively. The isolation forest algorithm is used to reduce the detection range of God class. In the stage of the intra-class measurement evaluation, the impact of the scale and architecture of the project is taken into account, and the average value of the God class related measurement indicators in the project is used as the benchmark. An experiment is designed to determine the scale factors, and the product of the average value and the scale factors are used as the threshold for the detection to obtain the God class detection result. The experimental results on the code smell benchmark data set show that the method proposed in this article improves the precision and
代码坏味主要用于描述面向对象代码中不合理的设计[
Fowler等人整理并总结了22种代码坏味(code smell)[
实验研究表明: 与具有上帝类的系统相比, 没有上帝类的系统会有更高的完整性、正确性与一致性[
本文提出了一种基于图模型和孤立森林的上帝类检测方法, 主要分为两个阶段: 图结构信息分析阶段和类内度量评估阶段. 图结构信息分析阶段利用类间调用图和类内结构图信息缩小上帝类的检测范围, 类内度量评估阶段从筛选后的类集合中通过对关键度量值的评估确定上帝类. 在图结构信息分析阶段, 从源代码中抽取方法调用信息, 构建类间方法调用图, 并对图中每个节点计算其节点中心度[
本文第1节对所用算法的背景知识进行说明和介绍. 第2节介绍上帝类检测的相关工作. 第3节重点阐述我们方法的设计思路和实现过程. 第4节介绍我们设计的4个评估实验和实验结果. 第5节对本文内容进行总结, 并展望未来的工作.
抽象语法树(abstract syntax tree, AST)是用树的形式来表示源代码. 抽象语法树用节点来存储代码里的各类信息, 其根节点对应着一个顶层编译单元, 直接与根节点相连接的节点表示源代码中的各种高级特征, 例如导入声明节点和类节点. 对方法声明节点而言, 其方法名称、返回值类型、方法体、方法修饰符等都是它的子节点. 抽象语法树就是通过这种形式来实现代码信息的存储. 我们从抽象语法树中提取方法调用信息, 利用调用信息构建方法调用图.
我们使用开源Java代码解析工具JavaParser[
PageRank是由谷歌的创始人Page等人提出的网页排序算法[
孤立森林(isolation forest)算法由Liu等人提出, 一般用于结构化数据的异常检测[
孤立森林算法采用随机分割数据集的方法, 异常点在孤立树上的路径较短, 容易在算法迭代的过程中被孤立分割, 而密度较高的正常点则需要进行多次切分才会被划分到孤立的区域. 孤立森林通过这种方法从数据集中检测出异常点.
利用孤立森林算法进行异常数据检测的样例
社区发现(community detection)算法主要用于发现网络中的社区结构[
根据使用挖掘算法的不同, 社区发现算法可以分为基于层次聚类的社区发现算法、基于随机游走的社区发现算法和基于模块度(modularity)的社区发现算法. 在本文中, 我们采用了基于模块度的算法Louvain[
其中,
Louvain算法的计算过程分为4步骤: (a) 将每个节点作为一个独立的社区; (b) 尝试将其分配到各个邻居节点所在的社区, 利用公式(1)计算分配前后的模块度, 进而得到分配后与分配前的模块度差值, 当该差值最大(且大于0)时, 所分配的邻居节点作为分配结果; (c) 迭代计算直到所有节点所属社区不再发生变化, 图中所有节点被分为4个社区; (d) 根据划分结果对现有的图结构进行压缩, 重新进行分配直到整个图的模块度不发生变化.
代码坏味的检测对提升软件质量非常重要, 也吸引到了很多研究者的关注[
上帝类作为一种较为典型的代码坏味, 也有很多相关的研究工作. 研究者们提出的检测上帝类的方法主要可以分为3种: 基于度量值的方法、基于机器学习的方法和基于深度学习的方法.
基于度量值的检测方法主要依赖于从代码中提取结构信息与指标, 例如类的加权方法数、内聚度、访问外部数据的个数等指标, 然后分别给不同的指标设立阈值, 将各项指标都满足阈值约束条件的类识别为上帝类[
Marinescu等人[
为了解决基于度量值的方法在阈值的选取上的主观因素对检测结果的影响, 近年来, 一些机器学习的方法也被应用于上帝类的检测上来, 并为上帝类的检测提供了一种新的视角[
与基于度量值的检测方法相比, 基于机器学习模型的检测方法能够解决基于度量值方法在检测和识别上帝类过程中阈值选择的问题, 同时, 机器学习的模型能够学习到各种特征之间深层的关系, 因此, 在识别的精确率和召回率上也有一定的提升. 但是现有的机器学习的方法同样没有结合项目特征, 例如类在项目中的重要程度、项目的方法调用图等.
近些年来, 随着深度学习技术的快速发展, 一些研究者们将深度学习的模型应用到上帝类的检测上来. Bu等人[
与机器学习的方法相比, 基于深度学习的方法使用了复杂的神经网络, 更能够拟合输入特征与代码坏味之间的关联关系, 从而有更高的识别精确率和召回率. 但是这些方法只针对类内的特征, 利用类内的信息作为输入得到上帝类的识别结果, 而忽视了类与类之间的关联关系, 更没有深入挖掘与分析类在系统中扮演的角色, 所以检测的精确率并不高. 我们使用方法调用图将系统中各个类之间的调用协作关系表示出来, 同时利用图论中的中心度的概念对每个类在系统中的重要程度进行建模, 提取到了上帝类的类间特征.
本文方法的概览如
基于图模型和孤立森林的上帝类检测方法概览
● 在图结构信息分析阶段, 利用项目的类间关系, 筛选出项目中的关键类. 关键类指的是在系统中承担较重要的功能、内部结构较为复杂的类. 首先建立项目类粒度的方法调用图, 同时, 为了衡量每个节点在方法调用图中的中心程度(该类在整个项目中的所担任的职责), 根据方法调用图, 分别计算每个节点的PR值和度中心性. 我们提出了这种假设: 在项目中占中心地位的类不一定是上帝类, 但是在项目中占据边缘地位并且与其他类关系不紧密的类一定不是上帝类. 我们根据上帝类内聚度不高、关注点较为分散的特点, 建立项目的类内结构图, 利用社区发现算法发现类内结构图中的社区数. 每个类中内部类的个数也是和上帝类有关的一种代码特征, 我们统计了每个类的内部类的个数. 将上面得到的这些数据作为孤立森林的输入特征, 以筛选出项目中关键类.
● 在类内度量评估阶段, 利用类内信息, 实现对上帝类的精确检测. 我们计算出项目内每个类的加权方法数度(WMC)、内聚度(TCC)、对外访问数(ATFD)和类内方法个数(NOM)等代码结构特征指标, 同时计算出每个项目中这些指标的平均值, 对每一个项目来说, 以这些指标的平均值和比例因子的乘积作为阈值进行筛选, 最终得到上帝类的检测结果.
代码信息抽取的整个工作流程主要可以分为3个步骤: 从待检测项目中提取Java源代码、利用静态分析工具将Java源代码解析为抽象语法树的表示形式、从抽象语法树中抽取方法调用信息并将信息保存到数据库.
对于每个待检测的系统, 利用上一步提取的类间的方法调用信息构建系统的类粒度的方法调用图, 并将其存入到图数据库Neo4j中. 因为我们只关注与类间的关系, 所以过滤了类内方法的相互调用, 只保留了类间的方法调用. 对于检测到的所有方法调用, 只需保留其中项目内的方法调用, 所以要过滤掉JDK的方法调用和第三方API的方法调用.
上帝类在项目中扮演着重要的角色, 上帝类一定是整个系统中较为关键的类. 利用这个特点, 我们可以从方法调用图中筛选出关键的类节点, 从而缩小我们的检索空间. 在建立方法调用图之后, 为了衡量图中每个节点在整个调用图中的重要程度, 我们使用到了节点中心度的概念. 根据方法调用图计算图中每个类节点在整个方法调用图中的中心度, 对每个类在整个项目中的重要程度进行建模.
我们分别选用PageRank算法计算出的PR值和图论中的度中心性(degree centrality)两种指标来衡量图中每个节点的重要程度. PageRank最早用于计算网页排名, 该算法同样可以应用于方法调用图中, 用于计算出方法调用图中每个类节点的重要程度, 计算过程如下.
(a) 给方法调用图中每个节点确定初始PR值, 初始值为1/
(b) 通过链接到每个节点的权重除以调用节点的方法调用总数, 连续更新每个节点的PR值.
(c) 重复上一步, 直至所有节点的PR值不再发生变化.
度中心性是网络中衡量节点重要性的指标. 度中心性使用一个节点的度数来衡量节点在图中的中心性, 最早来源于社会网络研究, 是研究人员为了确定社交网络中具有影响力的人而提出的概念. 度中心性基于这样一种假设: 节点拥有的边越多, 节点就越重要. 方法调用图中的每个节点, 都需要计算其度中心性的数值.
开源项目JEdit方法调用图中部分节点的PR值和度中心性计算结果如
JEdit项目方法调用图中部分节点PR值和度中心性计算结果
因为JEdit中类的数量过多, 所以我们只挑选了部分类进行展示. 图中每个节点代表一个类, 其中包含两个上帝类, 分别是jEdit和View: 类jEdit是整个应用程序的入口类, 混杂了文件读写、界面处理和缓存操作等多种关联性不强的功能; 类View主要用于处理整个程序视图相关的操作, 但也包含了配置相关的功能. 我们计算出每个类在方法调用图中的PR值和度中心性值(在图中用DC表示). 从图中可以看出, 上帝类View和jEdit的度中心性值和PR值明显要高于方法调用图中其他的类节点. 这说明PR值和度中心性可以有效地表示出上帝类的类间图结构特征.
上帝类的一个特征是单个类承担多种职责, 内聚度不高. 这种特征在图中的表现形式为类内部的联系不够紧密, 明显可以划分为几个社区. 我们使用社区发现算法对上帝类进行分析, 利用社区数目来衡量一个类内部的离散程度.
我们给项目中每个类构建了类内结构图. 图中的节点类型有两种: 方法节点和类内变量节点; 图中的关系类型有3种: 方法之间的调用(invoke)、方法使用类内变量(use)以及我们为了加强图中节点的联系而额外引入的方法同时被调用(co-invoked)关系. 组成一个功能内聚的几个方法不一定存在直接的调用关系, 仅使用调用和使用两种关系不能完全建模出内聚关系, 因此我们引入了同时被调用关系(co-invoked). 如果一个类中的方法同时被另外一个类调用, 就使用同时被调用关系将其关联起来, 利用同时被调用关系来加强内部节点之间的联系.
我们采用基于模块度的社区发现算法Louvain来挖掘每个类内部社区的数目, Louvain使用模块度来描述社区内紧密的程度. 其算法计算的主要过程如下.
(a) 每个节点作为一个社区, 初始的社区数目和节点的个数相同.
(b) 针对每个节点, 遍历该节点的所有邻居节点, 衡量把该节点加入其邻居节点所在社区所带来的模块度的收益, 并选择对应最大收益的邻居节点, 加入其所在社区. 重复计算, 直到所有的社区都不再发生变化.
(c) 将新的社区作为节点, 重复计算上一步的过程, 并使用两个社区之间相邻点之间的权重作为两个社区退化成一个点后的新的权重.
类内结构图的社区发现结果
孤立森林算法主要用于检测异常数据, 异常具有两个特点: 异常数据只占少量, 并且异常数据的特征值和正确数据差别很大. 我们利用异常数据的这两个特点, 将在整个项目方法调用图中的中心度较高并且内部离散程度较高的节点设为异常节点, 使用孤立森林算法, 从我们的数据集中筛选出上帝类的候选结果.
除了上一步计算出的PR值和度中心性两个值以外, 我们还计算了每个类的内部类个数. 在Java里面, 定义在一个类里面或者一个方法体里面的类被称为内部类, 内部类一般分别4种: 成员内部类、局部内部类、匿名内部类和静态内部类. 相较于没有内部类的类而言, 有内部类的类一般有着更复杂的内部结构、更复杂的功能, 也意味着该类在整个系统中有着更重要的地位. 我们利用PR值、度中心性和内部类的数量等指标, 将在项目中结构复杂、较为重要的类当作孤立森林算法中待检测的异常节点, 利用孤立森林算法对数据集进行筛选, 进一步缩小了我们的检索范围, 方便后面实现对上帝类的精确检测.
孤立森林的算法主要可以分为两个阶段: 训练阶段和测试阶段. 训练阶段通过对数据集采样的方式建立孤立树; 在测试阶段, 用孤立树为每一个测试样本来计算异常分数.
构建孤立森林的算法如下所示.
(1) 初始化森林, 设置孤立树的个数为
(2) 设置树的高度限制为
(3) 对于每一棵树, 将输入数据进行采样得到新的数据, 放入树的根节点.
(4) 随机指定一个维度, 根据指定数据的极值, 在当前数据中随机生成切割点
(5) 根据切割点生产的超平面, 将当前节点数据空间划分为两个不同的子空间, 则该维度空间中小于
(6) 在每个孩子节点中递归进行步骤(4)和步骤(5), 重复构造新的孩子节点, 直到所有的样本都已经被孤立, 或者孤立树达到指定高度.
基于度量值的上帝类检测方法使用固定的阈值来对上帝类进行筛选[
(1) 类的加权方法数(WMC): 一个类中所有方法的统计复杂度的和.
(2) 类内聚紧密程度(TCC): 通过访问相同的属性而发生联系的方法的个数.
(3) 访问外部数据的个数(ATFD): 对于一个给定的类, 它所访问的外部类的个数. 它可以直接访问这些外部类的属性, 也可以通过访问器方法访问这些属性.
(4) 类内方法个数(NOM): 即一个类中方法的个数.
上帝类的识别公式如下, 其中,
为了评估方法的有效性, 我们围绕以下4个问题开展了实验验证, 并与相关方法进行了对比.
● RQ1: 本文提出的方法是否优于现有方法?
● RQ2: 利用孤立森林算法是否能够缩小上帝类的检索范围?
● RQ3: 相关超参数对实验结果带来何种影响?
● RQ4: 本文提出的方法在时间性能上表现如何?
为了与现有的方法进行对比, 我们采用Palomba等人[
测试数据集的信息
项目名称 | 项目版本 | 类的数量 | 上帝类的数目 |
Ant | v1.8.2 | 1 166 | 6 |
Derby | v10.9.1.0 | 2 797 | 26 |
FreeMind | v0.9.0 | 438 | 2 |
Hadoop | v0.9 | 238 | 1 |
HBase | v0.94 | 1 054 | 8 |
Ivy | v2.0.0 | 330 | 2 |
JEdit | v4.5.0 | 513 | 6 |
JHotDraw | v7.5.1 | 613 | 2 |
Pig | v0.8.0 | 1 021 | 3 |
Qpid | v0.18 | 2 217 | 6 |
Structs | v2.2.1 | 1 837 | 2 |
Wicket | v1.4.20 | 2 002 | 4 |
Xerces | v2.3.0 | 718 | 6 |
现有的上帝类检测方法主要分为3类: 基于度量值的方法、基于机器学习的方法、基于深度学习的方法.由于Wang等人[
● 精确率(precision)的计算公式为
● 召回率(recall)的计算公式为
●
对比结果见
不同方法的上帝类检测结果对比
项目名称 | 我们的方法 | JDeodorant | 深度学习方法[ |
||||||
精确率(%) | 召回率(%) | 精确率(%) | 召回率(%) | 精确率(%) | 召回率(%) | ||||
Ant | 31.25 | 83.33 | 45.45 | 1.70 | 50.00 | 3.29 | 5.13 | 100.00 | 9.76 |
Derby | 50.00 | 70.37 | 58.46 | 4.01 | 42.30 | 7.33 | 5.05 | 92.30 | 9.58 |
FreeMind | 28.57 | 100.00 | 44.44 | 4.08 | 100.00 | 7.84 | 4.88 | 100.00 | 9.31 |
Hadoop | 16.67 | 100.00 | 28.58 | 0.00 | 0.00 | 0.00 | 3.84 | 100.00 | 7.40 |
HBase | 42.86 | 75.00 | 54.54 | 2.52 | 62.50 | 4.84 | 6.25 | 100.00 | 11.76 |
Ivy | 28.57 | 100.00 | 44.44 | 4.00 | 100.00 | 7.69 | 3.28 | 100.00 | 6.35 |
JEdit | 75.00 | 100.00 | 85.71 | 4.40 | 66.70 | 8.26 | 6.98 | 100.00 | 13.05 |
JHotDraw | 0.00 | 0.00 | 0.00 | 1.69 | 50.00 | 3.27 | 1.96 | 100.00 | 3.84 |
Pig | 30.00 | 100.00 | 46.15 | 0.00 | 0.00 | 0.00 | 2.16 | 100.00 | 4.23 |
Qpid | 14.29 | 66.67 | 23.54 | 3.23 | 83.30 | 6.22 | 3.49 | 100.00 | 6.74 |
Structs | 16.67 | 100.00 | 28.58 | 1.64 | 100.00 | 3.23 | 0.98 | 50.00 | 1.92 |
Wicket | 12.12 | 100.00 | 21.62 | 4.17 | 75.00 | 7.90 | 4.82 | 100.00 | 9.20 |
Xerces | 45.45 | 83.33 | 58.82 | 8.82 | 50.00 | 14.99 | 6.98 | 100.00 | 13.05 |
平均值 | 30.11 | 82.98 | 41.56 | 3.09 | 59.98 | 5.76 | 4.29 | 95.56 | 8.17 |
从表中可以看出: 与JDeodorant这种传统的基于度量值的方法相比, 我们的方法在精确率、召回率和
与深度学习的方法相比, 我们的方法在精确率和
为了深入分析检测结果, 我们分别统计分析了检测结果中的误报结果和漏报结果. 漏报结果是16条, 误报结果是132条. 漏报结果的PR值和度中心性值普遍较低, 漏报所有类的平均PR值和平均度中心性值分别为0.49和7.81, 低于所有项目中上帝类的平均PR值0.69和平均度中心性值9.30. 例如JHotDraw中被漏报的上帝类org.jhotdraw.draw.DefaultDrawingView, 该类的PR值为0.15, 度中心性值为2, 远低于上帝类的平均PR值和平均度中心性值. 因为漏报类的图特征并不突出, 所以被本文提出的方法所漏报. 误报类的平均PR值为1.15, 平均度中心性值为8.95, 误报类的平均PR值要高于上帝类, 平均度中心性值与上帝类均值较为接近. 因为误报类的图特征值接近或高于上帝类, 所以被本文提出的方法所误报. 这也说明了如果我们想进一步提升检测的精确率和召回率, 仅靠PR值和度中心性值这两种图特征是不够的, 还需要结合其他图结构特征.
为了探究我们提出的方法是否能够有效检索出项目中的上帝类, 进一步缩小我们的检索范围, 我们设计了实验对于这个过程进行评估. 我们分别统计了原数据集中类的总数和使用孤立森林之后类的总数, 统计结果见
孤立森林筛选前后数据对比
项目名称 | 原数据集 | 使用孤立森林筛选后 | ||||
类的 |
上帝类 |
筛选后 |
筛选后上帝 |
筛选后类的数量占 |
筛选后上帝类的数量 |
|
Ant | 1 166 | 6 | 144 | 6 | 12.35 | 100.00 |
Derby | 2 797 | 26 | 433 | 22 | 15.48 | 84.62 |
FreeMind | 438 | 2 | 66 | 2 | 15.07 | 100.00 |
Hadoop | 238 | 1 | 65 | 1 | 27.31 | 100.00 |
HBase | 1 054 | 8 | 346 | 8 | 32.83 | 100.00 |
Ivy | 330 | 2 | 58 | 2 | 17.58 | 100.00 |
JEdit | 513 | 6 | 134 | 6 | 26.12 | 100.00 |
JHotDraw | 613 | 2 | 59 | 0 | 9.62 | 0.00 |
Pig | 1 021 | 3 | 275 | 3 | 26.93 | 100.00 |
Qpid | 2 217 | 6 | 310 | 5 | 13.98 | 83.33 |
Structs | 1 837 | 2 | 153 | 2 | 8.33 | 100.00 |
Wicket | 2 002 | 4 | 174 | 4 | 8.69 | 100.00 |
Xerces | 718 | 6 | 70 | 6 | 9.75 | 100.00 |
总数/总比例 | 14 944 | 74 | 2 287 | 67 | 15.30 | 90.54 |
使用孤立森林算法前后数据集的对比结果如
在我们的孤立森林算法中, 对算法执行过程产生影响的主要是两个超参数: 采样的样本大小
数据集中, 上帝类的个数随孤立树的数量变化情况如
数据集中上帝类的个数和类的总数随孤立树数量变化情况
孤立树的数量从10变化到200, 对上帝类的筛选效果影响不大. 筛选后, 数据集中上帝类的数量和类的数量上下波动, 未出现明显的变化. 这说明构建孤立树数量在10−200之间都可以实现较好的数据过滤效果.
我们固定孤立树的数量为100, 然后调整采样数目, 观察筛选效果. 根据实验可以看出: 随着采样数量的增加, 孤立森林的筛选条件越来越严格, 精确率会得到一定的提高; 但是召回率会下降. 为了在保证较高召回率的同时尽可能地提高精确率, 我们选择128的采样数是比较合适的. 随着采样数量的变化, 数据集中上帝类的数量变化和类总数的数量变化如
数据集中上帝类的数量和类的数量随采样数目变化情况
为了探究以项目指标的平均值和比例因子的乘积作为阈值筛选上帝类时, 比例因子对实验结果的影响, 我们选择了4个指标用于最后精确筛选出上帝类, 分别是类的加权方法数(WMC)、类内聚的紧密程度(TCC)、访问外部数据的个数(ATFD)、类内方法个数(NOM)这4个指标[
比例因子对实验结果的影响
ATFD |
WMC |
NOM |
TCC |
平均 |
平均 |
平均 |
1 | 4 | 4 | 3 | 21.08 | 76.00 | 31.47 |
2 | 4 | 4 | 3 | 22.92 | 76.00 | 33.46 |
3 | 4 | 4 | 3 | 24.79 | 70.90 | 35.08 |
4 | 4 | 4 | 3 | 27.81 | 65.21 | 36.96 |
5 | 4 | 4 | 3 | 29.29 | 60.79 | 37.29 |
2 | 1 | 4 | 3 | 18.81 | 76.00 | 28.90 |
2 | 3 | 4 | 3 | 19.73 | 76.00 | 29.93 |
2 | 4 | 4 | 3 | 22.92 | 76.00 | 33.46 |
2 | 5 | 4 | 3 | 26.58 | 76.00 | 37.18 |
2 | 6 | 4 | 3 | 31.89 | 73.43 | 41.22 |
2 | 5 | 1 | 3 | 21.87 | 77.85 | 32.45 |
2 | 5 | 2 | 3 | 21.98 | 76.57 | 32.50 |
2 | 5 | 3 | 3 | 24.14 | 76.28 | 34.82 |
2 | 5 | 4 | 3 | 26.58 | 76.00 | 37.18 |
2 | 5 | 5 | 3 | 30.51 | 76.00 | 41.23 |
2 | 5 | 6 | 3 | 36.84 | 69.37 | 45.02 |
2 | 5 | 5 | 1 | 30.98 | 63.92 | 38.47 |
2 | 5 | 5 | 2 | 30.93 | 74.72 | 41.43 |
2 | 5 | 5 | 4 | 30.60 | 77.56 | 41.46 |
2 | 5 | 5 | 5 | 30.15 | 81.41 | 41.26 |
根据实验结果可知, 当ATFD, WMC, NOM和TCC这4个比例因子分别为2, 5, 5和6时, 检测结果最符合我们的预期.
为了评估本文所提出的方法的时间性能, 我们针对测试数据集上13个开源项目, 记录了本文提出的方法在各个步骤上完成计算所需要花费的时间(以s为单位), 见
在测试数据集上完成各个步骤所花费的时间
步骤名称 | 所花费的时间(s) |
解析源码 | 391.6 |
建立方法调用图 | 20.0 |
计算节点中心度值 | 3.9 |
建立类内结构图 | 21.1 |
社区发现算法 | 13.7 |
利用孤立森林识别关键节点 | 6.9 |
计算度量值 | 86.0 |
结果筛选 | 19.9 |
总时长 | 563.1 |
由
在对比评估实验中, 我们选用了开源代码坏味数据集中的13个开源项目作为测试项目, 数据集中的所有代码坏味都经过人工标注. 虽然与自动识别代码坏味的方法相比, 人工识别代码坏味有着更高的可信度, 但是人工标注的主观性差异也会对标注结果造成影响, 从而影响到标注结果的正确性. 此外, 仅用一个基准数据集难以验证我们的方法在其他数据集上也能取得预期的检测效果, 在后续的工作中, 我们将会用更多的开源数据集来对本文提出方法的正确性和有效性进行验证.
在探究比例因子的变化对实验结果带来何种影响的研究实验中, 我们选用了有限的比例因子组合进行实验并得到检测结果, 没有验证因子在全部取值范围内的实验结果. 选取范围的有限性, 使我们不能保证选取到了最优的比例因子组合. 为了使选取的比例因子组合尽可能地接近最优解, 我们设计了较多的组合值进行研究实验.
本文提出了基于图模型和孤立森林的上帝类检测算法, 主要可以分为两个阶段: 图结构信息分析阶段和类内度量评估阶段. 在图结构信息分析阶段, 我们的主要目的是利用图结构信息筛除项目中大量的非上帝类节点, 缩小上帝类的检测范围. 首先从项目源码中提取信息构建类粒度的方法调用图, 用类节点在方法调用图中的中心程度来衡量每个类在整个项目中的重要程度, 同时对每个类构建其类内结构图, 使用社区发现算法计算每个类内结构图中社区的数量, 用类内结构图中社区的数目对类的内聚程度进行建模. 为了尽可能缩小上帝类的检索范围, 我们使用了孤立森林的方法, 将图模型挖掘出的信息作为孤立森林算法的输入, 筛选出符合上帝类特征的类, 大大缩小检测范围. 在类内度量评估阶段, 为了进一步确定上帝类, 我们计算了和上帝类有关的度量值, 并计算出了这些度量值的项目平均值, 以度量值的项目平均值和比例因子的乘积作为阈值进行上帝类的检测. 对比实验结果表明: 我们目前提出的上帝类检测算法总体优于现有的基于深度学习的检测算法, 在精确率和
本文提出的上帝类的检测方法虽然相比于现有方法提升较大, 但是在精确率上仍有提升空间. 除了基于图的结构信息和度量值等信息以外, 代码文本中也蕴含了上帝类的特征信息. 在后面的工作中, 我们将提取代码中的文本信息, 包括用户自定义的标识符和注释中的文本, 结合自然语言处理领域的相关模型, 进一步提高对上帝类检测的精确率和召回率. 另一方面, 图模型不仅可以建模出上帝类的特征, 还可以扩展应用到其他类型的代码坏味, 例如特征依恋和霰弹式修改等. 在未来的工作中, 我们将研究用何种类型的图特征对其他类型的代码坏味进行建模, 使本文提出的基于图模型和孤立森林的检测方法可以扩展应用到更多类型的代码坏味上.
Fowler M, Beck K. Refactoring: Improving the Design of Existing Code. 2nd ed., Addison-Wesley Professional, 2018.
Nucci D, Palomba F, Tamburri D, Serebrenik A, Lucia A. Detecting code smells using machine learning techniques: Are we there yet? In: Proc. of the 25th Int'l Conf. on Software Analysis, Evolution and Reengineering. 2018. 612-621.
Deligiannis I, Stamelos I, Angelis L, Roumeliotis M, Shepperd M. A controlled experiment investigation of an object-oriented design heuristic for maintainability. Journal of Systems and Software, 2004, 72(2): 129-143.
Xu WB, Hua QB, Fei N. Object-oriented software refactoring. Computer Engineering, 2005, 31(5): 82-84 (in Chinese with English abstract).
许文波, 华奇兵, 费娜. 面向对象的软件重构. 计算机工程, 2005, 31(5): 82-84.
Tsantalis N, Chatzigeorgiou A. Identification of move method refactoring opportunities. IEEE Trans. on Software Engineering, 2009, 35(3): 347-367.
Vaucher S, Khomh F, Moha N,
Azadi U, Fontana FA, Taibi D. Architectural smells detected by tools: A catalogue proposal. In: Proc. of the 2nd Int'l Conf. on Technical Debt. 2019. 88-97.
Marinescu R. Detection strategies: Metrics-based rules for detecting design flaws. In: Proc. of the 20th Int'l Conf. on Software Maintenance. 2004. 350-359.
Munro M. Product metrics for automatic identification of "bad smell" design problems in Java source-code. In: Proc. of the 11th IEEE Int'l Software Metrics Symp. 2005. Article No. 15.
Moha N, Gueheneuc Y, Duchien L, Le Meur AL. DECOR: A method for the specification and detection of code and design smells. IEEE Trans. on Pattern Analysis and Machine Intelligence, 2010, 36(1): 20-36.
Palomba F, Bavota G, Penta MD,
Bu YF, Liu H, Li GJ. God class detection approach based on deep learning. Ruan Jian Xue Bao/Journal of Software, 2019, 30(5): 1359-1374 (in Chinese with English abstract). http://www.jos.org.cn/1000-9825/5724.htm [doi: 10.13328/j.cnki.jos.005724]
卜依凡, 刘辉, 李光杰. 一种基于深度学习的上帝类检测方法. 软件学报, 2019, 30(5): 1359-1374. http://www.jos.org.cn/1000-9825/5724.htm[doi: 10.13328/j.cnki.jos.005724]
Page L, Brin S, Motwani R, Winograd T. The Page Rank Citation Ranking: Bringing Order to the Web. Stanford Digital Libraries Working Paper, 1998.
https://enterprise.leanpub.com/javaparservisited]]>
Liu FT, Ting KM, Zhou ZH. Isolation forest. In: Proc. of the 8th Int'l Conf. on Data Mining. 2008. 413-422.
Liu FT, Ting KM, Zhou ZH. Isolation-based anomaly detection. ACM Trans. on Knowledge Discovery from Data, 2012, 6(1): 1-39.
Blondel V, Guillaume J, Lambiotte R, Lefebvre E. Fast unfolding of communities in large networks. Journal of Statistical Mechanics: Theory and Experiment. 2008, 2008(10): Article No. 10008.
Abbes M, Khomh F, Gueheneuc YG,
Yamashita A, Moonen L. Exploring the impact of inter-smell relations on software maintainability: An empirical study. In: Proc. of the 35th Int'l Conf. on Software Engineering. 2013. 682-691.
Zhang M, Hall T, Baddoo N. Code bad smells: A review of current knowledge. Journal of Software Maintenance & Evolution Research & Practice, 2011, 23(3): 179-202.
Tufano M, Palomba F, Bavota G,
Tufano M, Palomba F, Bavota G,
Zhang XF, Zhu C. Empirical study of code smell impact on software evolution. Ruan Jian Xue Bao/Journal of Software, 2019, 30(5): 1422-1437 (in Chinese with English abstract). http://www.jos.org.cn/1000-9825/5735.htm [doi: 10.13328/j.cnki.jos.005735]
章晓芳, 朱灿. 代码坏味对软件演化影响的实证研究. 软件学报, 2019, 30(5): 1422-1437. http://www.jos.org.cn/1000-9825/5735.htm[doi: 10.13328/j.cnki.jos.005735]
Arcoverde R, Garcia A, Figueiredo E. Understanding the longevity of code smells: Preliminary results of an explanatory survey. In: Proc. of the 4th Workshop on Refactoring Tools. 2011. 33-36.
Chatzigeorgiou A, Manakos A. Investigating the evolution of bad smells in object-oriented code. In: Proc. of the 7th Int'l Conf. on the Quality of Information and Communications Technology. 2010. 106-115.
Peters R, Zaidman A. Evaluating the lifespan of code smells using software repository mining. In: Proc. of the 16th European Conf. on Software Maintenance and Reengineering. 2012. 411-416.
Fokaefs M, Tsantalis N, Chatzigeorgiou A. JDeodorant: Identification and removal of feature envy bad smells. In: Proc. of the 23rd IEEE Int'l Conf. on Software Maintenance. 2007. 519-520.
Fontana FA, Mäntylä MV, Zanoni M,
Maiga A, Ali N, Bhattacharya N,
Maiga A, Ali N, Bhattacharya N, Sababe A, Guhneuc Y, Antoniol E, Ameur E. Support vector machines for anti-pattern detection. In: Proc. of the Int'l Conf. on Automated Software Engineering. 2012. 278-281.
Khomh F, Vaucher S, Gueheneuc Y, Sahraoui H. A Bayesian approach for the detection of code and design smells. In: Proc. of the 9th Int'l Conf. on Quality Software. 2009. 305-314.
Khomh F, Vaucher S, Gueheneuc Y,
Palomba F, Panichella A, Lucia AD,
Ma S, Dong D. Detection of large class based on latent semantic analysis. Computer Science, 2017, 44(S1): 495-498 (in Chinese with English abstract).
马赛, 董东. 基于潜在语义分析的Large Class检测. 计算机科学, 2017, 44(S1): 495-498.
Wang SY, Zhang YQ, Sun JZ. Detection of bad smell in code based on BP neural network. Computer Engineering, 2020, 46(10): 216-222, 230 (in Chinese with English abstract).
王曙燕, 张一权, 孙家泽. 基于BP神经网络的代码坏味检测. 计算机工程, 2020, 46(10): 216-222, 230.
Zhang HR, Wu YJ, Zhao WY. Software metrics set for code design quality monitoring. Computer Applications and Software, 2020, 37(3): 13-21, 66 (in Chinese with English abstract).
张海锐, 吴毅坚, 赵文耘. 面向代码设计质量监控的软件度量指标集研究. 计算机应用与软件, 2020, 37(3): 13-21, 66.
Palomba F, Bavota G, Penta MD, Fasano F, Oliveto R, De Lucia A. On the diffuseness and the impact on maintainability of code smells: A large scale empirical investigation. Empirical Software Engineering, 2018, 23(3): 1188-1221.