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 展示了文本分析的方式,以经文本标准化引擎处理的全部程序文本为训练集,将每一个类作为一篇文
   224   225   226   227   228   229   230   231   232   233   234