14

PMDを使用して、プロジェクトに関するコード品質レポートを生成しています。
NPathの複雑さの検査の結果がわかりません。
結果を表示する鈍いクラスを作成しました(これは実際のクラスではありませんが、同じパターンを使用しています)。

import java.util.*;

public class SOFExample {

    private final Map<String, Date> magicMap = new HashMap<String, Date>();    
    protected static final long UNKNWOWN = 0L;
    private static final class MyCal { long aTime; long bTime; long cTime; long dTime;}

    public void usefullMethod(final List<MyCal> myCals) {

        final Date a = magicMap.get("a");
        final Date b = magicMap.get("b");
        final Date c = magicMap.get("c");
        final Date d = magicMap.get("d");

        final long aTime = a == null ? UNKNWOWN : a.getTime();
        final long bTime = b == null ? UNKNWOWN : b.getTime();
        final long cTime = c == null ? UNKNWOWN : c.getTime();
        final long dTime = d == null ? UNKNWOWN : d.getTime();

        for (MyCal myCal : myCals) {
            if(myCal.aTime == UNKNWOWN) myCal.aTime = aTime;
            if(myCal.bTime == UNKNWOWN) myCal.bTime = bTime;
            if(myCal.cTime == UNKNWOWN) myCal.cTime = cTime;
            if(myCal.dTime == UNKNWOWN) myCal.dTime = dTime;
        }
    }
}

PMDの結果:

メソッドusefullMethod()のNPathの複雑さは10625です。

同じ方法で初期化された新しい変数を追加すると、次のようになります。

メソッドusefullMethod()のNPathの複雑さは103125です。

そして、私がすべてを交換した場合はどうなりますか?if-else構造では、次のようになります。

メソッドusefullMethod()のNPathの複雑さは1056です。

なぜ私は三元'でこの非常に高い結果を得たのですか?' オペレーター?

このコードの何が問題になっていますか?(このデモコードでは、デフォルト値を取得するためのメソッドを簡単に抽出できますが、実際のコードでは不可能な場合があります)

4

1 に答える 1

20

例をさらに簡単にすると、このクラスのnPath値は2になります。これが2である理由は明らかです。コードには、明らかに2つの実行パスがあります。

package test;

import java.util.*;

public class Test {

    private static final long UNKNWOWN = -1;

    public void method(Date a) {
        long aTime;

        if (a == null) {
            aTime = UNKNWOWN;
        } else {
            aTime = a.getTime();
        }
    }
}

そして、このクラスのnPath値は5です。問題は、コード内にまだ2つの論理パスがある理由です。

package test;

import java.util.*;

public class Test {

    private static final long UNKNWOWN = -1;

    public void method(Date a) {
        final long aTime = a == null ? UNKNWOWN : a.getTime();
    }
}

ただし、使用されるアルゴリズムは次のとおりです。

int npath = complexitySumOf(node, 0, data);     
npath += 2;

それはすべての子供たちの複雑さを追加し、次に三元のために2つを追加します。単純なJavaノードに対して返される最小の複雑さは1です。AbstractSyntaxTreeは3つの子があることを示しています。したがって、3+2は5です。

<ConditionalExpression beginColumn="36" beginLine="11" endColumn="69" endLine="11" ternary="true">
  <EqualityExpression beginColumn="36" beginLine="11" endColumn="44" endLine="11" image="==">
    <PrimaryExpression beginColumn="36" beginLine="11" endColumn="36" endLine="11">
       <PrimaryPrefix beginColumn="36" beginLine="11" endColumn="36" endLine="11">
         <Name beginColumn="36" beginLine="11" endColumn="36" endLine="11" image="a"/>
       </PrimaryPrefix>
    </PrimaryExpression>
    <PrimaryExpression beginColumn="41" beginLine="11" endColumn="44" endLine="11">
      <PrimaryPrefix beginColumn="41" beginLine="11" endColumn="44" endLine="11">
        <Literal beginColumn="41" beginLine="11" charLiteral="false" endColumn="44" endLine="11" floatLiteral="false" intLiteral="false" singleCharacterStringLiteral="false" stringLiteral="false">
          <NullLiteral beginColumn="41" beginLine="11" endColumn="44" endLine="11"/>
       </Literal>
      </PrimaryPrefix>
    </PrimaryExpression>
  </EqualityExpression>
  <Expression beginColumn="48" beginLine="11" endColumn="55" endLine="11">
    <PrimaryExpression beginColumn="48" beginLine="11" endColumn="55" endLine="11">
      <PrimaryPrefix beginColumn="48" beginLine="11" endColumn="55" endLine="11">
        <Name beginColumn="48" beginLine="11" endColumn="55" endLine="11" image="UNKNWOWN"/>
      </PrimaryPrefix>
     </PrimaryExpression>
  </Expression>
  <PrimaryExpression beginColumn="59" beginLine="11" endColumn="69" endLine="11">
    <PrimaryPrefix beginColumn="59" beginLine="11" endColumn="67" endLine="11">
      <Name beginColumn="59" beginLine="11" endColumn="67" endLine="11" image="a.getTime"/>
    </PrimaryPrefix>
    <PrimarySuffix argumentCount="0" arguments="true" arrayDereference="false" beginColumn="68" beginLine="11" endColumn="69" endLine="11">
      <Arguments argumentCount="0" beginColumn="68" beginLine="11" endColumn="69" endLine="11"/>
    </PrimarySuffix>
  </PrimaryExpression>
</ConditionalExpression>

三項演算子に複雑な式がある場合、それが数える違いはさらに一般的です。コードの何が問題になっているのかというと、すでに9つのブランチ(8つの三項演算子とループ)があり、nPathの計算全体がなくても高いです。関係なくリファクタリングします。

于 2011-02-27T16:35:59.260 に答える