Android 应用程序的代码异味检测工具与方法综述
2022-07-29王露颖边奕心
王露颖,边奕心,赵 松,朱 晓,涂 杰
(哈尔滨师范大学 计算机科学与信息工程学院,哈尔滨 150025)
0 引言
代码异味又被称为代码坏味道,最初是由Fowler提出的。代码异味的存在增加了程序的维护成本,降低了代码质量。近年来,随着移动通信技术的迅猛发展,移动应用程序已经成为软件行业的发展主体。因此,许多学者从不同的角度对Android应用程序中的代码异味进行了广泛和深入的研究,开发了许多Android 应用程序中代码异味自动检测工具。研究发现,用于检测传统桌面应用程序代码异味的检测工具也可检测Android 应用程序中的代码异味。但是,这些传统的工具只能检测Android应用程序中面向对象的代码异味。
不同于传统的桌面应用程序,Android 应用程序中除了存在面向对象的代码异味,还存在Android特有的代码异味。随着研究的不断深入,研究者不断提出针对Android 应用程序中Android 特有代码异味的检测方法和工具,以便于日后对Android 应用程序中特有的代码异味展开进一步的研究。
目前,针对Android 应用程序中的代码异味自动检测工具种类繁多,功能和适用环境各不相同。本文对比分析了目前具有代表性的Android 应用程序中的代码异味检测工具和方法,以便Android 应用程序的研究人员在面对实际代码异味时,能够选择合适的检测工具。
1 相关研究工作综述
本文重点关注Android 应用程序的代码异味检测工具。为了调查检测工具的应用情况,通过以下3 个步骤对文献进行检索:
(1)定义搜索字符串。本文定义了3 组搜索字符串用于文献搜索,见表1。主要在IEEE Xplore、ACM、Springer 和Google scholar 使用搜索字符串对文献进行了调查。
表1 用于文献调查的3 组搜索字符串Tab.1 Three sets of search strings for literatures survey
(2)选择主要研究对象。本文主要选取与Android 应用程序中代码异味研究相关的文献。
(3)筛选目前开源可获取的自动检测工具。在这一步中,过滤掉已经不可获取、无法用于今后研究的Android 应用程序代码异味自动检测工具。
本文最终选取了14 篇文献,见表2。可以发现,针对Android 应用程序中代码异味研究的论文,大多数都是在2015~2020 年发表的,并且在仅研究Android 应用程序中面向对象的代码异味时,研究人员大多仍使用传统的检测工具。
表2 Android 应用程序中代码异味的相关文献Tab.2 Literatures on code smells in Android applications
2 代码异味检测方法
2.1 代码异味检测流程
目前,代码异味检测方法的基本流程是相似的,如图1 所示。
图1 代码异味检测流程Fig.1 Code smells detection process
首先,对输入的项目源代码进行预处理,提取出待测文件(如.java、.c 文件等);其次,根据不同的检测方法,将处理好的代码传换成中间形式,如抽象语法树列等结构;最后,使用不同的检测方法对其中的代码异味进行检测,输出检测结果。
2.2 代码异味检测方法分类
由于代码异味的存在增加了系统维护的难度,给软件系统带来了长期隐患。因此,对软件系统中异味进行检测是很有必要的。现有的代码异味检测工具所使用的检测方法主要可以分为5 类。对此可给出研究分述如下。
(1)基于症状的检测方法。基于症状的异味检测方法是利用不同的症状和概念来描述代码异味,将异味的“症状”描述成中间形式后,转化为检测算法对其进行检测。
(2)基于度量的检测方法。基于度量的检测方法是最常用的代码异味探测方法。这种检测方法以逻辑表达式或条件表达式的形式,将一组度量和不同的阈值组合成一个检测规则,以检测代码中的不同异味。
(3)基于搜索的检测方法。基于搜索的检测方法源于基于搜索的软件工程(SBSE)相关研究。SBSE 使用基于搜索的方法来解决软件工程中的优化问题,其中绝大多数的技术都应用了机器学习算法。基于搜索的异味检测方法的提出,一定程度上弥补了之前的检测方法在精确度上的不足。
(4)基于概率的检测方法。基于概率的检测方法通过确定一个类中存在异味的概率,来识别代码中的异味类型。一些基于概率的检测方法,还应用了模糊逻辑规则和频繁模式树,对代码异味进行探测。
(5)基于可视化的检测方法。基于可视化的检测方法可以通过半自动化的过程来识别代码中的异味类型。该方法使用如面向可视化的策略和可视化设计缺陷检测策略等技术,将人类的专业知识与自动化的检测过程相结合。
现有的检测工具大多都是基于这些方法所提出的,本文对上述5 类检测方法的优缺点做了比较,见表3。
表3 不同代码异味检测方法比较Tab.3 Comparison of different code smells detection methods
3 Android 应用程序的代码异味检测工具
从对Android 应用程序中不同种代码异味检测的角度,可将现有Android 应用程序中代码异味检测工具分为3 类:一类是仅支持Android 应用程序中面型对象的代码异味检测的工具,另一类是仅支持Android 特有代码异味检测的工具,第三类是既支持面向对象、又支持Android 特有的代码异味检测的工具。目前,可用于Android 应用程序中代码异味检测的工具见表4。
3.1 仅支持面向对象代码异味检测的工具
已有研究表明,传统的代码异味检测工具可以用来检测Android 应用程序中面向对象的代码异味。表4中加粗的JSpIRIT、DECOR、TACO、JDeodorant 和organic 表示已经用于Android 应用程序中的代码异味检测研究。
表4 Android 应用程序中代码异味的检测工具Tab.4 Tools for detecting code smells in Android applications
同样用于Android 应用程序中面向对象的代码异味检测的工具还有inFusion。Mannan 等人使用inFusion 代码异味检测工具针对20 种面向对象的代码异味,分析了其在Android 应用程序和桌面应用程序中的分布差异。但Rahkema 等人研究面向对象代码异味在Android 和IOS 应用程序中的分布时,发现inFusion 代码异味检测工具目前已经无法获取。经过调查,当下作为商业软件的inFusion 确实已无法通过官方渠道免费获取。因此,后续无法使用inFusion 对Android 应用程序中面向对象的代码异味进行研究,但iPlasma 可以替代inFusion 对部分面向对象的代码异味进行检测。iPlasma 是一个面向对象软件系统质量评估的集成环境,相当于inFusion 的免费版。iPlasma 使用基于度量的方法对代码异味进行检测,但是iPlasma 的功能远没有inFusion 强大,也只能够检测到11 种代码异味,而inFusion 则可以检测到22 种代码异味。
综上所述,研究者在研究桌面应用程序中面向对象的代码异味时,开发的检测工具可以用于检测Android 应用程序中面向对象的代码异味。但是由于这些检测工具大多以插件的形式存在,所以在检测Andriod 应用程序中面向对象的代码异味时,存在局限性。目前,Androd 应用程序大多是在Android Studio 环境下开发的。而在此之前,Androd应用程序都是在Eclipse IDE 和ADT 环境下开发的。在2015 年6 月ADT 不再提供更新支持后,开发者逐渐使用Android Studio 开发Android 应用程序。因此,目前开源的Androd 项目存储库中混合了有Android Studio 和旧的Eclipse 开发的Android 项目。显然,在Android Studio 中运行JDeodorant、TACO、JSpIRIT 等来检测代码异味是不可能的,这就导致在运行以Eclipse 插件的形式存在的工具、对Android 应用程序中的代码异味进行检测时,会存在一些麻烦。虽然Google 公司为Eclipse 开发的Android 项目提供了自动迁移工具,使其可以由Android Studio 继续开发,但并不支持反向迁移的情况,这就意味着研究者要是想用JDeodorant、TACO、JSpIRIT 等检测由Andriod Studio 开发的Andriod 项目时,需要将Andriod Studio 项目文件夹修改为Eclipse 的正确结构,手动完成反向迁移,不利于大规模实验研究。
3.2 仅支持Android 特有代码异味检测的工具
目前,在对Android 特有代码异味的研究中,使用的开源可获取的自动检测工具主要有2 个:aDoctor 和DAAP。2 个检测工具的对比具体如下:
(1)2 个检测工具在设计时,参考的都是Reimann 等人提出的异味目录。
(2)2 个检测工具都利用抽象语法树当作中间形式来解析Java 程序。不同的是,DAAP 针对存在于XML 程序中的代码异味,使用文档对象模型(Document Object Model)来解析XML 程序。
(3)aDoctor 可以对其中5 种与能耗相关的代码异味进行重构,而DAAP 不能进行重构操作。
综合前述分析可知,目前针对Android 特有代码异味检测的开源工具还很少,且检测方法单一。
3.3 既支持面向对象又支持Android 特有代码异味检测的工具
Android 应用程序中不仅存在传统面向对象的代码异味,还存在Android 特有的代码异味。目前,2 类代码异味都可以检测的开源工具只有PAPRIKA。PAPRIKA 采用基于度量的检测方法,对Android 应用程序中的代码异味进行探测。PAPRIKA 通过以下步骤对Android 应用程序中的代码异味进行探测:
(1)解析Android 应用程序中的APK 文件,构建PAPRIKA 模型。首先,使用Soot 框架及其Dexpler 模块来分析APK 文件,从中提取度量信息,进而构造PAPRIKA 模型。
(2)将构建好的PAPRIKA 模型存储到一个图形数据库中。为了提供一种可扩展的方法来分析整个Android 应用程序,PAPRIKA 采用的是Neo4j 图形数据库来存储和查询构建好的PAPRIKA 模型,提取出度量信息。
(3)查询图,以检测Android 应用程序中的代码异味。当构建好的PAPRIKA 模型被图形数据库加载和索引时,就可以使用数据库查询语言来探测代码异味。
在此基础上分析可知,作为唯一一个既可以检测Android 应用程序中面向对象的代码异味和特有代码异味的工具,研究人员对PAPRIKA 检测的异味种类不断进行扩展。其中,Habchi 等人在研究Android 和IOS 应用程序中的代码异味时,对PAPRIKA 的功能进行了扩展,使其可以检测由C 和Swift 语言开发的IOS 应用程序中的代码异味。研究结果表明,Android 应用程序比IOS 应用程序中存在的异味数量更多。Carette 等人在分析Android特有代码气味对应用程序性能的影响时,对PAPRIKA 进行扩展使其可以检测和重构3 种Android 特有的代码异味。去除代码异味后,可以提高Android 应用程序的性能。Mateus 等人在研究由Kotlin 语言开发Android 应用程序是否可以提高软件质量时,改进PAPRIKA 使其可以检测由Kotlin语言开发的应用程序中的代码异味。最新研究指出,在由Kotlin 语言开发的Android 应用程序中,面向对象的代码异味更为常见。目前,PAPRIKA 最多可以检测4 种面向对象的代码异味、13 种Android特有的代码异味。
4 异味检测工具的评价
不同的检测工具对于不同规模、开发语言的项目具有不同的检测效果。目前,常用于评估检测工具性能的指标主要有 3 个,分别是查准率()、查全率()和值(),各指标数学定义分别如下:
其中,(True Positive)为被检测为正的正样本数;(False Positive)为被检测为正的负样本数;(False Negative)为被检测为负的正样本数。
在检测Android 应用程序中面向对象的代码异味时,研究人员常使用传统检测桌面应用程序中代码异味的工具。对于此类检测工具的检测精度评价已有大量研究进行了总结。其中,Lim重点评价了JSpIRIT、JDeodorant、DECOR 和TACO 四个传统的检测工具对Android 应用程序中代码异味的检测效果。结果表明,在对Andriod 应用程序中的代码异味进行检测时,4 个检测工具的漏检率极高。针对Andriod 应用程序中的异味Large Class,DECOR作为其中检测效果最好的工具,结果中的值仅为36%,而JDeodoran 则无法检测出该异味。
目前,缺少对Android 特有代码异味检测工具的系统评价。因此,本文首先使用DAAP、aDoctor和PAPRIKA 分别对异味忽略成员的方法(Member Ignoring Method,MIM)进行检测,然后利用查准率、查全率和值对3 个检测工具的检测效果进行评价,从而探讨3 个工具的检测精确度。MIM 是指某个类中的方法,该方法既是非静态方法,也是非空方法,但该方法没有访问所在类的任何属性。本文选取了6 个开源Android 应用程序作为待测试程序,详细描述见表5。
表5 6 个Android 应用程序及相关信息Tab.5 Six Android applications and related information
3 个检测工具对6 个Android 应用程序中异味MIM 的平均检测结果见表6,具体检测结果如图2所示。从表6 和图2 中可以看出,3 个工具对MIM的检测性能综合排名为:aDoctor>PAPRIKA>DAAP。由此可知,aDoctor 的检测效果最好,其值较DAAP 平均提高16.18%、较PAPRIKA 平均提高5.11%。
图2 不同工具在6 个Android 应用程序上的检测结果Fig.2 Detection results of different tools on 6 Android applications
表6 3 个检测工具对MIM 的平均检测结果Tab.6 Average detection results for MIM by 3 detection tools %
综上所述,3 个工具对MIM 的检测性能综合排名为:aDoctor>PAPRIKA>DAAP。aDoctor 作为检测效果最好的工具,值较DAAP 平均提高16.18%、较PAPRIKA 平均提高5.11%。
5 结束语
本文对近几年用于Android 应用程序中代码异味检测的工具和方法做了全面归纳与总结,并对Android 特有代码异味检测工具的性能进行了简单的评估。综合目前的实际需求,Android 应用程序中代码异味的检测工具和方法的未来研究方向包括:
(1)由于Android 应用程序与传统桌面应用程序在程序结构、API 调用、内存、CPU、网络、电池等方面的诸多差异,Android 应用程序中代码异味的种类及分布比传统桌面应用程序中的更复杂。因此,将传统的检测工具直接应用在Android 应用程序中的代码异味检测上,其检测效果差且存在局限性。目前,针对Android 应用程序中面向对象代码异味检测的工具仅有PAPRIKA 一个,且最多只能检测其中的4 种代码异味。为深入研究Android 应用程序中的代码异味,未来可以针对Android 应用程序的架构,提出适合且检测效果较好的代码异味检测工具。
(2)目前,针对Android 特有代码异味检测的具有代表性的工具只有DAAP、aDoctor 和PAPRIKA,且这3 个检测工具都是基于度量的检测方法所设计的。因此,在检测的过程中会受到阈值局限,出现漏检的情况,其检测结果也并不理想。因此,未来可以参考面向对象代码异味检测方法,基于其他检测方法研发出检测效果更好的检测工具。
(3)许多研究者在研究传统面向对象的代码异味时,针对多种异味之间的联系、如共存进行深入研究。而Android 应用程序中不仅存在面向对象的代码异味,还存在其特有的代码异味。因此,针对2 类异味之间存在的联系同样也亟待继续加大研发力度。目前,可同时检测2 类代码异味的工具有PAPRIKA,且其可检测的异味种类有限。因此,为了方便探索Android 应用程序中2 类代码异味之间的联系、进行大规模实验,未来可以继续对PAPRIKA 进行扩展,使其可以检测更多种类的代码异味,还可以继续探索其他检测方法来检测2 类代码异味,提出更高效、便捷的检测工具。
最后,本文研究可以给Android 应用程序中的代码异味的研究者提供一些参考,选择合适的检测和重构工具,有助于后续对Android 应用程序中的代码异味进行深入研究。