2

Cyclomatic Complexityは、与えられた関数がどれほど難しいか、またはバグを含む可能性がどれくらいあるかについての大まかな基準を提供します。私が読んだ実装では、通常、すべての基本的な制御フロー構造(if、case、while、forなど)が関数の複雑さを1増加させます。循環的複雑さは、仮想関数が呼び出す "プログラムのソースコードを通る線形に独立したパスの数"は、実行時にどの実装が呼び出されるのかのあいまいさのために、関数の循環的複雑さも増加させるはずです(呼び出しは、実行)。仮想関数呼び出しの循環的複雑さは何ですか?

しかし、同等のswitch文(問題の仮想関数を実装している階層内のすべてのクラスに対して1つのcaseキーワードを使用して、各caseキーワードに対して1つのポイントを含む)と同じ量をペナルティ化すると、仮想関数呼び出しは一般的にはプログラミングの面で優れていると考えられています。

仮想関数呼び出しの循環的複雑さにはどのようなコストが必要ですか?私は、私の推論が、循環的複雑さをメトリクスとして、あるいは仮想関数の使用やそれとは別のものとして利用することに対する議論であるかどうかはわかりません。

編集:人々の反応の後、大規模なswitch文を含むグローバル関数への呼び出しと同等の仮想関数呼び出しを考えることができるので、循環的な複雑さを増やすべきではないことに気付きました。この関数はスコアが悪くても、プログラム内には1回しか存在しませんが、各仮想関数呼び出しをswitch文で直接置き換えると、コストが何度も発生します。

+1

あなたの質問は、基本的にプログラムが何を理解するのが難しいかを測定する「グローバルな複雑さ」と、基本的にテストを書くことがどれほど難しいかを測定する「ローカル複雑さ」の違いの大きな例を指摘しています定義されたすべてのメソッドのカバレッジソフトウェアプロジェクトが成長するにつれて、これらの複雑さの概念が収束する傾向にあると思いますが、小規模のコードベースでは、循環複雑性のような指標に基づくベストプラクティスは「グローバルな複雑さ」(すなわち仮想関数) "ローカルな複雑さ"(すなわち、 "スイッチ")。 – Peter

+0

私は、この質問に対する答えは、switch文よりも悪いとマークされるべきであると考えています。分離されたモジュール内の多態的な呼び出しを考慮すると、本当に無制限のスイッチなので、実際にあるかもしれない)。プログラム全体の知識の観点から考えると、スイッチとして考えるべきです。このメトリックで*同等と見なすからといって、他のメトリック(多態性が勝っている望ましい効果を得るために変更する必要がある行数など)に沿ってコードの品質を評価することはできません。 –

答えて

5

通常、循環型の複雑さは関数呼び出しの境界には適用されませんが、関数内のメトリックです。したがって、仮想呼び出しは、仮想ではない静的関数呼び出し以上にはカウントされません。

2

仮想関数呼び出しでは、関数の呼び出しの外部にあるため、実装が「あいまいさようなら」と呼ばれるため、循環的な複雑さは増しません。オブジェクトの値が設定されると、あいまいさはありません。どのメソッドが呼び出されるかは正確に分かります。

BaseClass baseObj = null; 
// this part has multiple paths & add to CC 
if (x == y) 
    baseObj = new Derived1(); 
else 
    baseObj = new Derived2(); 

// this part has one path and does not add to the CC 
baseObj.virtualMethod1(); 
baseObj.virtualMethod2(); 
baseObj.virtualMethod3(); 
0

私は循環器系の複雑さの大ファンではありませんが、この場合は関数を呼び出しています。 (クラス階層設計が本当に台無しにならない限り)ほぼ同じことを行い、それに応じていくつかのバリエーションがあります。あなたが関数を呼び出すと、渡す引数に応じてさまざまな動作を得ることができますが、これはCCではカウントされません。

したがって、私はその費用を完全に無視しています。

+0

"クラス階層設計が本当にうんざりしていない限り、ほぼ同じことになります。それに応じていくつかのバリエーションがあります。" - Barbara Liskov、1987 –

1

仮想関数の呼び出しが原因で実装が ランタイム

ああで呼ばれるその 曖昧で、同様 機能の 循環的複雑度を増やす必要がありますが、それは曖昧ではありませんランタイム(メタプログラミング/サルのパッチ適用をしている場合を除きます)。それは受信機のタイプ/クラスによって完全に決定される。

関連する問題