Help us understand the problem. What is going on with this article?

循環的複雑度について

背景

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

循環的複雑度とは?

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

循環的複雑度(英: 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

yut_arrows
Java/Kotlin/Springを書いてきましたが、書けるとは一言も言ってないです
https://yu-tarrrr.hatenablog.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした