Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
142
Help us understand the problem. What is going on with this article?
@yut_arrows

循環的複雑度について

More than 1 year has passed since last update.

背景

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

循環的複雑度とは?

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

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

142
Help us understand the problem. What is going on with this article?
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
yut_arrows
Java/Kotlin/Spring/Elixir

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
142
Help us understand the problem. What is going on with this article?