LoginSignup
229
173

More than 3 years have passed since last update.

循環的複雑度について

Last updated at Posted at 2018-10-14

背景

  • 仕事でコーディングをしていた際に、上長から複雑度について指摘された
  • 循環的複雑度という単語は知らなかったが、なんとなくバグが潜みそうなのはわかっていた
  • せっかくなので、循環的複雑度について調べてみた
  • 僕と同じくらいの経験が浅い人が対象

循環的複雑度とは?

とりあえず調べてみた、、、

循環的複雑度(英: Cyclomatic complexity)とは、ソフトウェア測定法の一種である。 Thomas McCabe が開発したもので、プログラムの複雑度を測るのに使われる。 プログラムのソースコードから、線形的に独立した経路の数を直接数える。wikipedia

要するに

  • コードの中にif/else・for文・switch文などの分岐がいくつ含まれているかを計算する
  • その数値の大小により、バグの混入しやすさがわかるというもの

具体的な数え方

  • 何も分岐がないプログラムは「1」
  • 分岐(if/else・for文・switch文・while文)がある度に「1」を加算する

一般的な考え

諸説あるみたいですが、、、

循環的複雑度 状態
1-10 安全なコードでテストしやすい
11-20 少し複雑なコード
21-40 複雑なコードでテストが難しくなる
41以上 やばいやつ。テスト不可能

普通に書いていれば、10を超えることはなかなかないと思います。(私の場合、ビジネスロジックのところで20を計測したことが1度ありました)

実際に例を用いて考える

以下に適当なサービスを用意してみました。あくまでも、例なので処理自体に意味はないので、無視してください。

Service.java

private String familyService(List<String> nameList) {
    String id;
    for (String name : nameList) {
        if (name.startsWith("a")){
            id = "a";
        } else if (name.startsWith("b")){
            id = "b";
        } else if (name.startsWith("c")){
            id = "c";
        } else if (name.startsWith("d")){
            id = "d";
        } else if (name.startsWith("e")){
            id = "e";
        } else if (name.startsWith("f")){
            id = "f";
        } else if (name.startsWith("g")){
            id = "g";
        } else if (name.startsWith("h")){
            id = "h";
        } else {
            id = "xxxx";
        }
    }
    return id;
}

上の例ですと、for文が1つとif/elseの分岐が9つあるので、1+1+9で複雑度は11になります。

対策

循環的複雑度を下げる方法はいくつかあると思います。

  • if文の条件を見直す
  • 共通化できるものは切り出す
  • クラスやメソッドとして新たに切り出す
  • メソッドの責務を見直す

などなど、やり方はいくらでもあると思うので、どちらかというと普段からコーディングする際に循環的複雑度を意識することが大事なのだと思います。
私、個人としては循環的複雑度について調べたおかげで目視で計算できるようになったのですが、全員が全員そうではないと思うので、そういった方のために、IntelliJ IDEAの機能を紹介しておきます。

用意したもの

  • IntelliJ IDEA

やりかた

  • IntelliJ >> preference を選択
    スクリーンショット 2018-10-14 12.55.49.png

  • 「overly complex」で検索する
    スクリーンショット 2018-10-14 12.58.12.png

  • クラス・メソッド単位で設定する
    設定値を超えるとこんな感じに怒られます。
    スクリーンショット 2018-10-14 13.01.39.png

まとめ

  • 循環的複雑度の考え方は簡単
  • 一度理解しておけば、リファクタリングやレビューのタイミングで役に立つ

参考にしたサイト

循環的複雑度 - Wikipedia
Learn Mccabe's Cyclomatic Complexity with Example

229
173
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
229
173