ファイル内のすべてのセクションの循環的複雑度の合計は、このファイルの循環的複雑度の合計ですか?そうである場合、関連ファイルのセットの合計は、このセットの循環的複雑度の合計ですか?
私が見たサイクロマティック複雑度の例のほとんどはコードの断片からのものであり、ファイル全体のサイクロマティック複雑度が計算される例に出くわしたことがないので、これは私にとって混乱です。
私の仮定が間違っているとすれば、一連のソースコードフラグメントの循環的複雑度を集計する適切な方法は何ですか?
私はこの質問を可能な答えとして指摘しました 私のコードの「循環的複雑度」とはどういう意味ですか? しかし、質問では、別々のコードフラグメントの循環的複雑度を集計する方法について説明します。
CCの合計がCCの総計であるというあなたの仮定は正しいですが、おそらくあまり役に立ちません。
循環的複雑度は、制御フローグラフに基づいています。通常、単一関数の制御フローグラフのみを確認します。すべての関数がmain()
にインライン化されているかのように、プログラム全体の制御フローグラフも確認できます。 CCは不当に大きくなり、有用な情報がほとんど伝わらないため、プログラム全体を見るのはあまり役に立ちません。
McCabeは、非構造化プログラムのコンテキストで循環的複雑性を開発しました。if/ else、ループ、および関数ではなく、gotoまたはジャンプを中心に構築されています。彼の動機の一部は、構造化および非構造化機能の正しい使用がプログラムを単純化できることを示すことです。また、「構造化プログラム」の用語も定義しています。基本的に、彼は次のように提案しています。コードスニペットを関数に抽出できる場合、その複雑さを1として数えることができます。この関数の内部の複雑さは関係ありません。結果として、main()
関数で始まる「構造化プログラム」は、プログラム全体で循環的複雑度1を持ちます。
余談ですが、例外を使用できるのは技術的にこの構造化プロパティに違反することを指摘しておきます。例外をスローできる関数には1つのエントリポイントがありますが、two出口点:通常の戻り用とスロー用。別の興味深い質問は、ポリモーフィックな呼び出し、つまりOOPメソッド呼び出しをカウントする方法です。ポリモーフィックな呼び出しサイトは特定の関数にジャンプしませんが、実行時に動的に関数を選択します。呼び出しは無限の循環的複雑性を持っているかもしれません。
では、一連の関数の組み合わされた循環的複雑性について話すことは意味がありますか?少なくとも実際にはそうではありません。これらの機能は独立しています。それらが互いに呼び出して制御フローグラフを共有する場合でも、それらを構造化プログラムとして扱い、呼び出された制御フローグラフを無視できます。保守性にとって重要なのは、それ自体がすべての機能です。
ただし、すべての関数の循環的複雑度を単純に追加することは基本的に正しいです。呼び出しを無視すると、各関数には独立した入口点と出口点があります。結合された制御フローグラフは存在しますが、disconnectedです。個々の循環的複雑度の合計は、コードを通る独立したパスの数を正確に表します。間違いなく、外部から呼び出すことができるパブリック関数のみを含め、プライベート関数を含めないことが正しいでしょう。
私たちは、保守性の尺度として、またそれが何をするのか理解するのがどれほど難しいかについての、1つのコード単位の特性について話している。クラスに多数のメソッドがある、またはファイルに多数のクラスがあるだけでは必ずしも複雑さに影響しないため、ファイルに適用しても意味がありません。より多くのメソッド、クラス、またはファイルにロジックコンポーネントはありません。