詳細
なぜ循環的複雑度なのか?
現時点では内部のコードの品質を包括的に評価する指標は存在しない。(すなわちクソコードをクソコードだと言うための数値がない)
しかし、いくつかの指標やツールはコードの構造の重要な観点を計測するのに役に立つ。
明確に計測可能なコードの観点で、循環的複雑度で表現される複雑さがある。
循環的複雑度
循環的複雑度は、客観的な複雑度合いの尺度を提供するために設計されたコードレベルの指標だ。
何が言いたいかというと、 「このコードはこれぐらい複雑なんだよ?」 と言うための指標だ。
例えば、
-
if文を一個もつ関数は二つの実行可能なパスがあるため
CC=2
となる -
反対に、if文を持たない関数は
CC=0
となる
循環的複雑度合いは、次のような公式で定義される
CC = E - N + 2
なんでこの式になったのか?は分からないので触れない。
ここで、
-
CC:循環的複雑度合い(Cyclomatic Complexity)
-
N :ノード(分岐点の数,ifやelse ifの数)
-
E :エッジ(コードが分岐する道の数,)
具体例を見てみよう
循環的複雑度のサンプル
次のような、java言語っぽいコードを見てみよう
public void decision(int c1, int c2){
if (c1 < 100) {
return 0
}else if ( c1 + c2 > 500){
return 1
}else{
return -1;
}
}
この場合、
-
E :エッジの数:returnを通る3つのパスで E=3
-
N :ノードの数:if文とelse if文の2つの分岐点で N=2
よって
CC = 3-2+2 = 3
という計測結果が出る。
循環的複雑度の一般化
循環的複雑度の式に出てくる2と言う数字は、一つの関数の単純化を表している。
他の関数を呼び出している場合は、循環的複雑度の公式は次にように変化(一般化)される。
CC = E - N + 2P
Pは関数内部で呼び出している他の関数の数である。
循環的複雑度はどれくらいの値だと良いのか
一般的に、IT業界におけるCCの閾値は、他の要素を考慮しない場合は10以下であることが推奨されている。
ただし、別の方の意見ではこの値はまだまだ高く、よくできた凝縮されたコードは5以下に収まっている。
あるケースでは、商用ソフトウェアパッケージの心臓部分として機能していた関数のCCが800を超えていた。
この関数では4000以上のコードを持ち、GOTO文を多用していたのだ。
循環的複雑度はどうすれば減るのか?
結論:テスト駆動開発をせよ
テスト駆動開発のようなエンジニアリングプラクティスでは、
-
コードを書く前にまずテストを書く。
-
そして、テストが通るためのコードを書く
と言う手順で開発を行なっている。
このエンジニアリングプラクティスでは、関数をテストしやすいようにキープするために必然的にサイズが小さくなる傾向がある。
これはテスト駆動開発の主目的ではないが、間違いなくポジティブな副作用である。
詳細