web-dev-qa-db-ja.com

循環的複雑度とは何ですか?

私が時々目にする言葉は「循環的複雑さ」です。ここでSO「言語XのCCを計算する方法」または「CCの最小量でYを実行するにはどうすればよいですか」に関するいくつかの質問を見ましたが、本当にわかりませんそれが何であるかを理解してください。

NDepend Webサイト で、基本的に「メソッド内の決定の数。各if、for、&&などがCCの「スコア」に+1を追加する」という説明を見ました。それが「はい」の場合、なぜこれが悪いのでしょうか?コードを理解しやすくするために、ifステートメントの数をかなり少なくした方がいいかもしれませんが、これは本当にすべてのことですか?

それとも、より深いコンセプトがありますか?

69
Michael Stum

私はもっ​​と深い概念を知りません。私はそれが保守性指標の文脈で一般的に考慮されると私は信じています。特定のメソッド内にあるブランチが多いほど、そのメソッドの操作のメンタルモデルを維持することが(一般的に)困難になります。

サイクロマティックの複雑度が高いメソッドは、単体テストで完全なコードカバレッジを取得することも困難です。 (ありがとう Mark W !)

もちろん、保守性の他のすべての側面をもたらします。エラー/回帰/などの可能性。ただし、コアコンセプトはかなり単純明快です。

52
Greg D

循環的複雑度は、そのブロックを通過するすべてのパスを実行するために、さまざまなパラメーターを使用してコードのブロックを実行しなければならない回数を測定します。カウントが多いと、論理的なエラーがテスト戦略をエスケープする可能性が高くなるため、好ましくありません。

38
Tetsujin no Oni
Cyclocmatic complexity = Number of decision points + 1

決定ポイントは、if、if…else、switch、forループ、whileループなどの条件ステートメントである場合があります。

次の表は、アプリケーションのタイプを示しています。

  • 循環的複雑度は1〜10ですNormal通常のアプリケーションと見なされます

  • 循環的複雑度は11〜20適度なアプリケーション

  • 循環的複雑度は21〜50危険なアプリケーション

  • 循環的複雑度は50を超えるapplication不安定なアプリケーション

12
Nirali

ウィキペディアはあなたの友達かもしれません: 循環的複雑度の定義

基本的に、プログラムを 制御フローグラフ として想像する必要があります。

複雑さは(...)として定義されます:

M = E − N + 2P

どこ

  • M =循環的複雑度、
  • E =グラフのエッジの数
  • N =グラフのノード数
  • P =接続されているコンポーネントの数

CCは、プログラムがどれほど複雑で、1つの整数でテストすることがどれほど難しいかを把握しようとする概念です。

11
azheglov

うん、それだけです。コードが実行できる実行パスが多いほど、テストが必要なものが多くなり、エラーの可能性が高くなります。

7
nikudesu

私が聞いたもう一つの興味深い点:

最大のインデントを持つコード内の場所は、最高のCCを持つ必要があります。これらは、読み取り/保守が難しくなることが予想されるため、一般的にテストカバレッジを確保するための最も重要な領域です。他の回答が指摘するように、これらはカバレッジを確保するためのコードのより難しい領域でもあります。

4
steamer25

循環的複雑性は本当に恐ろしい流行語です。実際、これはソフトウェア開発でコードのより複雑な部分を指摘するために使用されるコードの複雑さの尺度です(バグが多い可能性が高いため、非常に注意深く徹底的にテストする必要があります)。 E-N + 2Pの式を使用して計算できますが、プラグインで自動的に計算することをお勧めします。コードの可読性と保守性を維持するために、CCを5未満に保つよう努力する必要があるという経験則を聞いたことがあります。

私は最近 Eclipseメトリックプラグイン を実験しましたJavaプロジェクト、そしてそれはもちろんあなたの通常のEclipseと統合する本当に素敵で簡潔なヘルプファイルを持っていますヘルプと、コードを改善するためのさまざまな複雑さの対策やヒントやコツのいくつかの定義を読むことができます。

3
Peter Perháč

つまり、アイデアは、CCが低いメソッドの方がフォークやループが少ないため、メソッドがより複雑になるということです。アナライザーを使用して500,000行のコードを確認し、CCがはるかに高い2つの方法があることを想像してみてください。これにより、理解を深めるためにこれらのメソッドをリファクタリングすることに集中できます(CCが高いとバグ率が高くなることも一般的です)。

2
JoshBerke

ルーチン内の各決定ポイント(ループ、スイッチ、ifなど...)は、基本的に、同等のifステートメントにまとめられます。 ifごとに、2つのコードパスを取得できます。したがって、1番目のブランチには2つのコードパスがあり、2番目のブランチには4つの可能なパスがあり、3番目には8つのパスがあります。少なくとも2 ** Nのコードパスがあり、Nはブランチの数です。

これにより、コードの動作を理解し、Nがいくつかの数を超えたときにコードをテストすることが困難になります。

2
Michael Burr

循環的複雑度は、制御フローグラフを使用して計算されます。プログラムのソースコードを介した線形独立パスの量的測定の数は、循環的複雑度(if/if else/for/while)と呼ばれます。

2
Asiri Harisandu

これまでの回答では、ソフトウェアの品質と循環的複雑度との相関については触れられていません。調査によると、サイクロマティック複雑度の指標が低いほど、高品質のソフトウェアの開発に役立つはずです。読みやすさ、保守性、および移植性のソフトウェア品質属性に役立ちます。一般に、5〜10の循環的複雑度メトリックを取得しようとする必要があります。

循環的複雑度などのメトリックを使用する理由の1つは、一般的に人間は脳内で同時に約7(プラスまたはマイナス2)の情報しか追跡できないことです。したがって、ソフトウェアが非常に複雑で、複数の決定パスがある場合、ソフトウェアの動作を視覚化することはできません(つまり、循環的複雑度のメトリックが高くなります)。これにより、エラーのあるソフトウェアやバグの多いソフトウェアが開発される可能性が高くなります。これに関する詳細情報は here および Wikipedia にもあります。

2
Jay Abraham

関数の 制御フローグラフ を検討します。追加のEdgeが出口から入口まで実行されています。循環的複雑度は、グラフを2つに分割せずに実行できるカットの最大数です。

例えば:

function F:
    if condition1:
       ...
    else:
       ...
    if condition2:
       ...
    else:
       ...

Control Flow Graph

制御フローグラフ

リンクされたグラフの循環的複雑度が3である理由を直感的に理解できるでしょう。

1
Craig Gidney

循環的複雑度は、基本的に、保守性のためにより多くの注意が必要なコードの領域を把握するための指標です。基本的には、リファクタリングへの入力です。これは、深くネストされたループや条件などを回避するという点で、コード改善領域を示しています。

1
aJ.

そういうことです。ただし、「case」または「switch」ステートメントの各分岐は1としてカウントされる傾向があります。実際には、これはCC hatesケースステートメント、およびそれらを必要とするすべてのコード(コマンドプロセッサ、ステートマシン、等)。

1
T.E.D.

循環的複雑度は、ソフトウェアのユニットがどれほど複雑であるかを示す尺度です。条件付き論理構造を使用してプログラムがたどる可能性のあるさまざまなパスの数を測定します(if、while、for、switch&caseなど...)。計算の詳細については、こちらのすばらしいYouTube動画をご覧ください https://www.youtube.com/watch?v=PlCGomvu-NM

プログラムが取ることができるさまざまなパスまたはシナリオを明らかにするため、テストケースの設計において重要です。 「優れたテスト容易性と保守性を実現するために、McCabeは、プログラムモジュールが循環的複雑度10を超えないようにすることを推奨しています」(Marsic、2012、p。232)。

参照:Marsic。、I。(2012年9月)。 ソフトウェアエンジニアリング。ラトガース大学。 www.ece.rutgers.edu/~marsic/books/SE/book-SE_marsic.pdfから取得

0
perfo