Checkstyle の Metrics 近辺の内容を日本語で分かり易く
個人的にチェックスタイルでもっとも素晴らしいチェックの項目群だと思うのだけど、これで引っかかると、意味が理解できなくて直すの止める人とか、「チェックが開発の邪魔だ」とか言ってくる人が多いので、なるだけ分かり易くメモしておく。
BooleanExpressionComplexity
要するに &&
とか ||
を繋げすぎた条件式なんてバグるんだから書くんじゃないというチェック。
この数値は、条件結合数( ||
や &&
の数 )で単純増加する。
個人的にここの 3 位が好み。
人間の脳みそは 同時に 5 個位しか処理できない そうですよ。
パラメータ
名称 | 意味 | 初期値 |
---|---|---|
max | 最大で許容する複雑度の数字 | 3 |
tokens | チェックする演算子 | && & || | ^ |
ClassDataAbstractionCoupling
中で使用(new とか)しているクラス数チェック。
何より、論理クラスをたくさん import しておいて、見通しが効くのかって問題がある。
これで何がわかるかというと、クラス保守のしやすさ(当たり前だけど、たくさん依存してるクラスなんてテスト書けないぞ)。
もっというと、数字が大きい=そのクラス色々やりすぎてないか?設計粒度おかしくない?って話
パラメータ
名称 | 意味 | 初期値 |
---|---|---|
max | 最大で許容するクラス数 | 7 |
excludedClasses | チェック対象外クラス(こいつらは論理ロジックではないので、無視する) | HashMap, ArrayList, String, float, TreeSet, List, Boolean, Void, Override, Short, IllegalArgumentException, UnsupportedOperationException, HashSet, void, Character, IndexOutOfBoundsException, byte, double, Double, LinkedList, Float, Byte, SortedMap, Long, Throwable, Object, Class, Map, IllegalStateException, Set, StringBuilder, SuppressWarnings, SortedSet, long, RuntimeException, Deprecated, NullPointerException, Queue, SecurityException, FunctionalInterface, TreeMap, Deque, int, Exception, Integer, SafeVarargs, StringBuffer, boolean, char, short, ArrayIndexOutOfBoundsException |
excludeClassesRegexps | チェック対象外クラスの正規表現。Voクラスなんかの設定をしておくと吉 | ^$ |
excludedPackages | チェック対象外パッケージ。ユーティリティパッケージでも指定しておくと吉 | {} |
ClassFanOutComplexity
参照しているクラス数。
ClassDataAbstractionCoupling
に似ているが、こっちはファイル単位で参照してるクラス数のカウント。
あくまで参照のカウントなので、中でインスタンス化してるかは問題ではなくて、メソッドの返り値を使ったとかそういうレベルでもカウントされる。
ClassDataAbstractionCoupling
に比べると数字が上がり易くなる傾向はあるが、この値が大きいということは、把握すべきクラス数が多いことを意味してる。
あんまし大きいと、テストコードが書きにくくなる。
個人的にもこれはデフォルトくらいでよい
パラメータ
名称 | 意味 | 初期値 |
---|---|---|
max | 最大で許容するクラス数 | 20 |
excludedClasses | チェック対象外クラス(こいつらは論理ロジックではないので、無視する) | HashMap, ArrayList, String, float, TreeSet, List, Boolean, Void, Override, Short, IllegalArgumentException, UnsupportedOperationException, HashSet, void, Character, IndexOutOfBoundsException, byte, double, Double, LinkedList, Float, Byte, SortedMap, Long, Throwable, Object, Class, Map, IllegalStateException, Set, StringBuilder, SuppressWarnings, SortedSet, long, RuntimeException, Deprecated, NullPointerException, Queue, SecurityException, FunctionalInterface, TreeMap, Deque, int, Exception, Integer, SafeVarargs, StringBuffer, boolean, char, short, ArrayIndexOutOfBoundsException |
excludeClassesRegexps | チェック対象外クラスの正規表現。Voクラスなんかの設定をしておくと吉 | ^$ |
excludedPackages | チェック対象外パッケージ。ユーティリティパッケージでも指定しておくと吉 | {} |
CyclomaticComplexity
循環的複雑度とよく言われる。
10 超えたら、汚すぎて読めないっていって、レビュー突っ返していいレベル(だと個人的に思ってる)。
関数型プログラミングやってる連中だと、これで 5 行くとか、よほどの理由があるかさもなくばバカかと思われる。
if
とか while
とかを使うことで発生する、処理分岐数の概算値。
具体的には boolean 式 1 個単位でカウントしてる
公式曰く「テストコードを書く前提なら、1-4 に抑えたい。5-7 ならかろうじてテストできるんじゃない?8-10 も行ったらリファクタを検討すべき。」
著作権法はプログラムにするとバグりやすい って話の中で、ドワンゴ CTO の人が、以下のように言及してる。
循環的複雑度が75を超えるとバグの混入確率は98%、「いかなる変更も誤修正を生む」状態になる
個人的見解なら 5 超えたらテストコード書きたくない時点でクソコードだと断じたい。
パラメータ
名称 | 意味 | 初期値 |
---|---|---|
max | 最大許容する分岐数 | 10 |
switchBlockAsSingleDecisionPoint | switch 分岐はcase含めて 1 とカウントするか?(false では case ごとにカウント) | false |
tokens | チェック項目 | while do for if switch case catch ?(三項演算子) && || |
JavaNCSS
コメント化されてないソースのステートメント(処理)数カウンタ。
公式曰く:
理論的根拠:大きすぎるメソッドやクラスは読みにくく、維持するのに費用がかかります。 NCSSの数値が大きいということは、メソッドやクラスが、より小さな単位に分解されるべき責任や機能を多すぎることを意味します。
個人的には methodMaximum = 20, classMaximum = 500 位の設定がテストしやすいのでオススメ。
関数型言語やってる人なら多分この位でいけるはず。
パラメータ
名称 | 意味 | 初期値 |
---|---|---|
methodMaximum | 1メソッドあたりの最大ステートメント数 | 50 |
classMaximum | 1クラスあたりの最大ステートメント数 | 1500 |
fileMaximum | 1 ファイルあたりのステートメント数 | 2000 |
NPathComplexity
Cyclomatic complexity(循環的複雑度)に近しい計算。
ただし、こちらの数字はネストすると単純カウントではなくて、条件分岐なら条件式の複雑性、三項演算は +2 補正とか、もう少し厳密に計算されれる。
ただ、「やりすぎてロジックの明瞭性を損なうなよ」とは checkstyle 公式の言。
個人的には 100 は超えたくない。
名称 | 意味 | 初期値 |
---|---|---|
max | NPathの最大許容値 | 200 |
ということで、主要なものの説明。