# 循環的複雑度：コードの複雑さを数字で測る方法

URL: https://formula.dog/ja/journal/formula-dog-cyclomatic-complexity-ja
Type: blog
Locale: ja
Published: 2026-08-01
Updated: 2026-08-27

---

> 複雑度が高いコードはバグが増えやすく、テストコストも膨らむ。循環的複雑度を計算して、保守性を数字で可視化し、リファクタリングの優先順位をつけよう。

複雑なコードは読みづらく、バグも増えやすい。でも「複雑さ」ってどうやって測るんでしょう？そこで登場するのが**循環的複雑度**（Cyclomatic Complexity）。数学的な方法で、コードの複雑さを1つの数字で表せます。

この指標を理解すれば、コードの品質をより客観的に判断できるようになります。テストすべき箇所も見つけやすくなるし、リファクタリングの優先順位もつけやすい。さらに、Excel の複雑な数式にも同じ考え方が使えます。

## 循環的複雑度の計算式：M = E - N + 2P

循環的複雑度を求める最も一般的な公式がこれです。

**M = E - N + 2P**

各記号の意味：

- 
**M** = 循環的複雑度（Cyclomatic Complexity）

- 
**E** = 制御フローグラフの辺の数

- 
**N** = ノードの数

- 
**P** = 独立した接続成分の数（通常は 1）

実際には、決定点の数を数えるショートカット法がより直感的です。

**CC = 判定（条件）の数 + 1**

こちらの方が覚えやすいし、手計算でもサッと出せます。if、switch、for、while、catch などの判定ポイントを1つ数えるたびに1を足していくだけです。

## 実例：Python の関数で計算してみる

具体例がないとわかりにくいですよね。こんな Python の関数を見てください。

`def process_order(order):
    if order.is_valid():
        if order.total() > 1000:
            discount = 0.2
        else:
            discount = 0.1
    else:
        return None
    
    if order.user_type() == "vip":
        discount = 0.3
    elif order.user_type() == "regular":
        discount = 0.15
    else:
        discount = 0
    
    return order.total() * (1 - discount)`![](https://fdzlnqpwsaniezitwiuw.supabase.co/storage/v1/object/public/cms-media/formula-dog/2026-08/10095b-inline1.webp)

この関数の循環的複雑度は？判定を数えます：

- 
`if order.is_valid()` → 1

- 
`if order.total() > 1000` → 1

- 
`if order.user_type() == "vip"` → 1

- 
`elif order.user_type() == "regular"` → 1

- 
`else` → 1（追加される）

ショートカット法：**CC = 判定の数 + 1 = 4 + 1 = 5**

この関数は複雑度 5。そこまで悪くない範囲ですが、機能が増えるにつれてこの数字は膨れていきます。

## 複雑度スコアの意味：何が「危険」なのか

数字が出たら、それが何を意味するのか知る必要があります。業界の一般的な基準はこちら。

- 
**1～10**：低リスク。テストしやすく、保守しやすい。理想的。

- 
**11～15**：中程度のリスク。テストカバレッジを上げる必要あり。

- 
**16～20**：高リスク。リファクタリング推奨。バグが潜みやすい。

- 
**21 以上**：危険度最高。即座にリファクタリングすべき。テストも困難。

チーム全体の平均を取ることも大事です。「この関数だけ複雑」ではなく、「全体的に複雑さが高い」というなら、コードレビューのプロセスや設計の見直しが必要かもしれません。

## 循環的複雑度と認知的複雑度：よく混同される違い

ここで注意が必要です。「複雑度」という言葉は複数の定義があります。

**循環的複雑度（Cyclomatic Complexity）** = テストの難しさを測る指標。判定の数で純粋に計算します。

**認知的複雑度（Cognitive Complexity）** = 人間がコードを読んで理解するのがどれだけ難しいか。ネストの深さや論理の複雑さをより詳しく数値化します。

![](https://fdzlnqpwsaniezitwiuw.supabase.co/storage/v1/object/public/cms-media/formula-dog/2026-08/e9c9a1-inline2.webp)

例えば、ネストが深い if 文は、循環的複雑度は変わらなくても、認知的複雑度は上がります。つまり、循環的複雑度は「テストすべき経路の数」で、認知的複雑度は「読むのにかかる脳力」なんです。

Linter（SonarQube など）を設定するとき、どちらを優先するかで戦略が変わります。多くの現代的なツールは認知的複雑度を推奨しています。

## Excel の複雑な数式も同じ問題を抱えている

プログラマーだけの話じゃありません。Excel や Google Sheets で複雑な数式を組んだことがあるなら、この問題は他人事ではないはずです。

`=IF(A1>100,IF(B1="approved",A1*0.9,A1*0.8),IF(C1>50,A1*0.7,A1))`こんな入れ子数式、見たことありますよね？このネストの深さと判定の数が、「複雑さ」を生みます。

同じロジックを以下のように分割すれば、ずっと読みやすく、バグも減ります。

`E2: =A1 * lookup_discount(B1, C1)  (複雑度 1)`ヘルパー関数に処理を分ける。これが「複雑度を下げる」ことの本質です。

## 循環的複雑度を下げる 5 つの方法

数字が高くなってしまった。じゃあどうするか？

### 1. ガード句を使う（Early Return）

ネストを減らす最も簡単な方法。条件を先に判定して、該当しなきゃ早めに return。

`# Before (複雑度 4)
def validate_user(user):
    if user.is_active():
        if user.age >= 18:
            if user.has_permission():
                return True
    return False

# After (複雑度 3)
def validate_user(user):
    if not user.is_active():
        return False
    if user.age < 18:
        return False
    if not user.has_permission():
        return False
    return True`
### 2. 関数を分割する
責任を1つに絞った小さな関数に分ける。各関数の複雑度が下がれば、全体の保守性も上がります。

### 3. ルックアップテーブルを使う

判定が多い場合、辞書や配列で値をマッピング。

`DISCOUNT_MAP = {
    "vip": 0.3,
    "regular": 0.15,
    "guest": 0.0
}

discount = DISCOUNT_MAP.get(user_type, 0.0)  # 複雑度 1`
### 4. ポリモーフィズムを活用する（OOP）
クラスやインターフェースで判定を分散。if-else チェーンではなく、オブジェクト指向の仕組みで処理を振り分けます。

### 5. 関心の分離（Separation of Concerns）

「何をするのか」ではなく「何を判定するのか」を明確にしたら、判定ロジックと実行ロジックを別ける。テスト範囲も狭くなります。

## 複雑度を自動で計算するツール

手計算も大事ですが、プロジェクト全体を把握するなら自動ツールが必須。

- 
**SonarQube**：最も有名。リーダーボードにも認知的複雑度を表示。CI/CD パイプラインに組み込める。

- 
**Code Climate**：クラウドベース。git とも連携。複雑度に基づいて A～F ランク。

- 
**Pylint / Flake8**（Python）：`pylint --disable=all --enable=R0912` で複雑度チェック。

- 
**ESLint**（JavaScript）：プラグイン `eslint-plugin-sonarjs` で cyclomatic complexity 測定。

- 
**Roslyn Analyzers**（C#）：Visual Studio に統合。

ほぼ全ての言語に対応ツールがあります。チームで統一ツールを選んで、基準を決めておくと、PR レビューもやりやすくなります。

## 複雑度を測るなら、こんなツールが役に立つ

複雑度の計測を習慣化するには、以下のようなツールがあると便利です。

## よくある質問（FAQ）

**循環的複雑度が高いと何が問題なの？**

判定ポイントが多いほど、テストケースが指数関数的に増えます。全ての分岐をテストしようとすると、コストが膨大になります。また、複雑なコードは読みづらく、バグも増えやすい。

**複雑度 10 を超えたら即座にリファクタリング必須ですか？**

必須ではありません。チームの方針次第。ただし、15 を超えたら真剣に考えるべき。新規開発では複雑度 10 以下が目安。既存コードのリファクタリングは段階的に進めるのがいい。

**自動生成されたコードの複雑度はどう扱う？**

計測の対象から外すか、別の基準を設けるのが一般的。自動生成コードはテスト対象にしないことも多いですし。

**Google Sheets や Excel のマクロにも使える？**

もちろん。VBA の関数の複雑度も同じ方法で計算できます。ただし VBA の場合、認知的複雑度の方が重要かもしれません（ネストが深くなりやすいため）。

**認知的複雑度と循環的複雑度、どっちを優先すべき？**

新規プロジェクトなら認知的複雑度。既存コードの改善なら循環的複雑度から始める方が実装しやすい。最終的には両方監視するのが理想的。

**複雑度の基準を下げるべき小さなチームは？**

むしろ下げるべき。少人数だからこそ、1 人が去ると知識が失われやすい。複雑度を低く保つことで、共有と保守がラクになります。

## FAQ

### 循環的複雑度が高いと何が問題なの？

判定ポイントが多いほど、テストケースが指数関数的に増えます。全ての分岐をテストしようとすると、コストが膨大になります。また、複雑なコードは読みづらく、バグも増えやすい。

### 複雑度 10 を超えたら即座にリファクタリング必須ですか？

必須ではありません。チームの方針次第。ただし、15 を超えたら真剣に考えるべき。新規開発では複雑度 10 以下が目安。既存コードのリファクタリングは段階的に進めるのがいい。

### 自動生成されたコードの複雑度はどう扱う？

計測の対象から外すか、別の基準を設けるのが一般的。自動生成コードはテスト対象にしないことも多いですし。

### Google Sheets や Excel のマクロにも使える？

もちろん。VBA の関数の複雑度も同じ方法で計算できます。ただし VBA の場合、認知的複雑度の方が重要かもしれません（ネストが深くなりやすいため）。

### 認知的複雑度と循環的複雑度、どっちを優先すべき？

新規プロジェクトなら認知的複雑度。既存コードの改善なら循環的複雑度から始める方が実装しやすい。最終的には両方監視するのが理想的。

### 複雑度の基準を下げるべき小さなチームは？

むしろ下げるべき。少人数だからこそ、1 人が去ると知識が失われやすい。複雑度を低く保つことで、共有と保守がラクになります。