1. 導入:なぜコードの「複雑さ」を測る必要があるのか?
プログラムを書いていると、「この関数、なんだか条件分岐だらけで読みづらいな…」と感じることはありませんか?複雑なコードはバグの温床になりやすく、修正するたびに別の場所で不具合が発生するリスクが高まります。そんな「コードの複雑さ」を数値として可視化できる指標が循環的複雑度です。これを知ることで、自分のコードが「どれだけテストしにくいか」を客観的に把握し、リファクタリングのタイミングを判断できるようになります。
2. 基礎知識:循環的複雑度とは?
循環的複雑度とは、プログラム内の「独立した実行経路」の数をカウントしたものです。簡単に言えば、if文やfor文、while文などの条件分岐が増えるほど数値が高くなります。
一般的に、このスコアが「10以下」であれば管理可能な複雑度とされ、11を超えるとテストが困難になり、メンテナンス性が著しく低下すると言われています。この数値が高いことは、その関数が「やりすぎ(責務が大きすぎる)」であるというサインです。
3. 実装・解決策:複雑度を下げる「早期リターン」
複雑度を下げるための最も簡単なテクニックが早期リターン(Early Return)です。深いネスト(if文の中にif文が入る状態)を解消し、条件を満たさない場合はすぐに処理を終了させることで、コードの可読性とテストのしやすさが劇的に向上します。
4. サンプルプログラム:リファクタリング前後の比較
以下のコードは、ユーザーの権限によって処理を分ける例です。
【リファクタリング前:複雑度が高い(ネストが深い)】
function processUser(user) {
// 条件が重なり、複雑度が高い状態
if (user.isActive) {
if (user.hasPermission) {
if (user.isAdmin) {
return “管理者用ダッシュボードを表示”;
} else {
return “一般ユーザー用画面を表示”;
}
} else {
return “権限がありません”;
}
} else {
return “アカウントが無効です”;
}
}
【リファクタリング後:早期リターンで複雑度を改善】
function processUser(user) {
// 異常系を先に処理(早期リターン)することでネストを解消
if (!user.isActive) return “アカウントが無効です”;
if (!user.hasPermission) return “権限がありません”;
// 正常系の処理がフラットになり、読みやすくなる
if (user.isAdmin) {
return “管理者用ダッシュボードを表示”;
}
return “一般ユーザー用画面を表示”;
}
5. 応用・注意点:現場での活用法
現場では、手動で計算するのではなく、静的解析ツール(ESLintのcomplexityルールや、SonarQubeなど)をCI/CDパイプラインに組み込み、自動的にスコアを計測するのが一般的です。
注意点:
・数値を下げることだけを目的にしない:無理にコードを分割しすぎて、逆に処理の流れが追いにくくなっては本末転倒です。
・目的は「保守性」:複雑度を下げるのは、あくまで「未来の自分やチームメンバーが修正しやすくするため」であることを忘れないでください。
まずは現在のプロジェクトで、一番ネストが深い関数を一つ選んで「早期リターン」で書き直すことから始めてみましょう。それだけで、コードの品質は大きく改善されます。

コメント