Page 229 - 《软件学报》2021年第8期
P. 229
黄子杰 等:检测 JavaScript 类的内聚耦合 Code Smell 2511
数和类的成员尚可明确,仍可利用以上信息得知引用操作的数量.
CDISP 的计算依赖 FDP 和 CINT.本文对 CINT 的检测不作改动,使用非严格的 FDP 个数检测方式:对于不
涉及函数入参的数据访问,沿用原 FDP 的检测方式,若无法检测到所属类,则将其视作一个单独的 FDP;对于涉
及函数入参的数据访问,则计算 WRFDP.
WRFDP(FDP with weighted reference)是面向入参外部引用权重的度量,具体方式为:对于函数 f,有入参集
合 P f .计算 f 在所属类中被调用的总次数 ntc(number of total calls).遍历 P f ,对 P f 的每个元素 p ,计算 p 被调用
i f i f
时入参形参的所属类为外部类的次数 ncfp(number of calls as foreign param).计算 ncfp 与 ntc 比值,其值域在[0,1]
之间.ncfp 计算的基本思路是:分析被检函数的每次调用,若调用的入参不源于所属类,则计入 ncfp.
对于被检函数的每个入参,均计算其 WRFDP,如式(2)所示.
ncfp ( p )
WRFDP (,f p i f ) = ntc ()f i f (2)
非严格的 NSFDP 的计算公式如式(3)所示.
NSFDP ()f = N (FDP ( ))f − N (P + f ) ∑ WRFDP ( ,f p i f ) (3)
本文将非严格的 NSCDISP 作为 DC 的强度(intensity)值 I dc ,其计算公式为
⎧ 0, CINT ( )f < 动态阈值
I dc ()f = NSCDISP ( )f = ⎪ NSFDP ()f (4)
⎨
⎪ , CINT ( )f ≥动态阈值
⎩ CINT ()f
NSCDISP 和 CINT 的检测阈值(文献[16]中的 HIGH)取系统检测结果的平均数(AVG)与标准差(STDEV)之
和 [17] ,未达到阈值的相关度量值将被改为 0,下同.
在计算出软件系统内的全部 I dc 后,对于该系统的全部函数{f 1 ,f 2 ,f 3 ,…,f i },可以得到一个集合 SI dc ={I dc (f 1 ),
I dc (f 2 ),I dc (f 3 ),…,I dc (f i )},对所得结果进行 Min-Max 标准化,使其值域落入[0,1]区间,得出最终的强度值集合 NSI dc
(normalized structural intensity),如式(5)所示.
NSI ()f = I dc () min( )f − I (5)
i
dc i max( ) min( )I − I
3.1.2 结构方式检测 FE
对于被检类 C current ,遍历系统的类全集 C.对于 C 中的每个元素 C i ,检测 C current 对 C i 成员(函数、属性)经去
重后的访问次数 a i ,并依据 a i 的值对 C 中的类从大到小排序,若排序第一的类 C top 不等价于 C current ,则判定存在
FE.将 C current 对 C top 的成员访问次数 a top 记为 ATFM(access to foreign members),将 C current 对自身的成员访问次
数 a current 记为 ATLM(access to local members),FE 的强度为式(6) [20] .
I fe =ATFM(C)−ATLM(C) (6)
若 I fe >0,即可判定 FE 存在.用类似第 3.1.1 节的方式对所得结果进行 Min-Max 标准化,得到结果集合 NSI fe .
3.1.3 结构方式检测 Blob
利用结构方式检测 Blob 有两个角度:类的体积和类的内聚性 [26] .前者根据代码长度或类成员的总数,后者
采用 LCOM5(lack cohesion of method 5)度量.由于本文的主题仅和内聚、耦合相关,且类体积相关的度量需指定
固定的阈值,故不将类的体积纳入检测考虑的因素.
对于类 C,获取其函数成员总数 k、属性成员总数 l、被访问的自身成员(函数、属性)经去重后的总数 a,定
义 LCOM5 为式(7),其值域在[0,2]间,检测阈值取第三分位点(75%)的值 [27] .
akl−
5( ) =
NSI () = C LCOM C (7)
blob
l − kl
用类似第 3.1.1 节的方式对所得结果进行 Min-Max 标准化,得到结果集合 NSI blob .
3.2 基于文本分析的强度检测算法
图 4 展示了文本分析的方式,以经文本标准化引擎处理的全部程序文本为训练集,将每一个类作为一篇文