post Image
Objective-C の循環的複雑度を計測する

諸般の事情があり Objective-C のコードをレビューしているが、if else のネストが多く循環的複雑度を計測したくなったので計測してみた。

循環的複雑度(CCN)って?

循環的複雑度は英語で cyclomatic complexity number であり、 CCN と略される。

ざっくり言うと、if や switch が多いコードは分岐が多くなるので、その分岐を数字で表したもの。
CCN が 10 以下なのは良い構造であり、それ以上はよろしくないとされている。
(指標なので、絶対的にそうだというわけではない)

が、個人的に CCN が 5 を超えるとコードを追うのが辛くなってくる。(コードにもよるが)

計測してみる

OCLint で開発しながら計測するのがよさそうだが、今回はとりあえず計測だけしたかったので OCLint は使っていない。

terryyin/lizard で ObjC の CCN を計測

他にも色々とあるようだが、 GitHub で検索して出てきた terryyin/lizard を使ってみる。

Mac なら python 入っていると思うので、 pip で install できる。

$ pip install lizard

実際に計測

Pods や gem なども計測対象になるので、計測したいコードがあるディレクトリに移動して lizard コマンドを実行する。

$ cd PROJECT_ROOT/PROJECT
$ lizard -Tcyclomatic_complexity=10
================================================
  NLOC    CCN   token  PARAM  length  location
------------------------------------------------
       3      1     19      0       4 application: didFinishLaunchingWithOptions:@18-21@./AppDelegate.m
       2      1      9      0       4 applicationWillResignActive:@24-27@./AppDelegate.m
       2      1      9      0       4 applicationDidEnterBackground:@30-33@./AppDelegate.m
       2      1      9      0       3 applicationWillEnterForeground:@36-38@./AppDelegate.m
       2      1      9      0       3 applicationDidBecomeActive:@41-43@./AppDelegate.m
       2      1      9      0       3 applicationWillTerminate:@46-48@./AppDelegate.m
       5      1     35      2       5 main@12-16@./main.m
       3      1      8      0       4 viewDidLoad@17-20@./ViewController.m
       3      1      8      0       4 didReceiveMemoryWarning@23-26@./ViewController.m
5 file analyzed.
==============================================================
NLOC    Avg.NLOC  AvgCCN  Avg.token  function_cnt    file
--------------------------------------------------------------
      3       0.0     0.0        0.0         0     ./AppDelegate.h
     17       2.2     1.0       10.7         6     ./AppDelegate.m
      5       5.0     1.0       35.0         1     ./main.m
      2       0.0     0.0        0.0         0     ./ViewController.h
     10       3.0     1.0        8.0         2     ./ViewController.m

=============================================================================================
No thresholds exceeded (cyclomatic_complexity > 10 or length > 1000 or parameter_count > 100)
==========================================================================================
Total nloc   Avg.NLOC  AvgCCN  Avg.token   Fun Cnt  Warning cnt   Fun Rt   nloc Rt
------------------------------------------------------------------------------------------
        37       2.7     1.0       12.8        9            0      0.00    0.00

作成して何もしていない Project なので問題のあるコードはないと出ている。

if 文を大量に置いて計測

精神が不安定になるコード:

- (void)viewDidLoad {
    [super viewDidLoad];
    if (true) {
        if (true) {
            if (true) {
                if (true){
                    if (true){
                        if (true){ }
                    }
                }
            }
        }
    } else {
        if (true) { }
    }
    if (true) { }
    if (true) { }
    if (true) { }
    if (true) { }
}

lizard を実行

$ lizard -Tcyclomatic_complexity=10
... 略 ...

=========================================================================================
!!!! Warnings (cyclomatic_complexity > 10 or length > 1000 or parameter_count > 100) !!!!
================================================
  NLOC    CCN   token  PARAM  length  location
------------------------------------------------
      21     12     77      0      22 viewDidLoad@17-38@./ViewController.m

CCN が 12 になりました、Warning で教えてくれています。

コードの品質を計測することができました :tada:
(ただし、 CCN はあくまで一つの指標です)

こうならないために

早期リターンをしたり、メソッドの分割をしてネストを浅くしていきましょう :muscle:

おまけ

本当に 10 以下なら問題ないと言えるのか?

このコードで CNN は 7 、だがどう見てもこれは… :scream:

- (void)viewDidLoad {
    [super viewDidLoad];
    if (true) {
        if (true) {
            if (true) {
                if (true){
                    if (true){
                        if (true){ }
                    }
                }
            }
        }
    }
}

Swift も計測できる

いま仕事で書いているコード。
SwiftLint で設定しているのでそれと同じ結果だが、 Swift の場合 enum の switch case 増えるしそこで CCN 高くなると思うのだが皆どうしているんだろう。

========================================================================================
!!!! Warnings (cyclomatic_complexity > 5 or length > 1000 or parameter_count > 100) !!!!
================================================
  NLOC    CCN   token  PARAM  length  location
------------------------------------------------
      18     15    127      1      18 hoge@134-151@./Hoge/Error.swift
      30      8    142      1      31 hoge@28-58@./Hoge/Message.swift
      11      6    117      0      11 hoge@59-69@./Hoge/Controller.swift

『 Swift 』Article List
Category List

Eye Catch Image
Read More

Androidに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

AWSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Bitcoinに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

CentOSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

dockerに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

GitHubに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Goに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Javaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

JavaScriptに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Laravelに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Pythonに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Rubyに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Scalaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Swiftに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Unityに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Vue.jsに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Wordpressに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

機械学習に関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。