PhpMetrics実行時に出力される指標の定義、数字の見方について調べてみたメモ

こういうやつです。

~~~ 
LOC
    Lines of code                               13930
    Logical lines of code                       7666
    Comment lines of code                       6264
    Average volume                              73.08
    Average comment weight                      40.21
    Average intelligent content                 40.21
    Logical lines of code by class              20
    Logical lines of code by method             10

Object oriented programming
    Classes                                     381
    Interface                                   74
    Methods                                     772
    Methods by class                            2.03
    Lack of cohesion of methods                 1.51

Coupling
    Average afferent coupling                   0.83
    Average efferent coupling                   3.03
    Average instability                         0.84
    Depth of Inheritance Tree                   1.26

Package
    Packages                                    113
    Average classes per package                 4.03
    Average distance                            0.14
    Average incoming class dependencies         4.11
    Average outgoing class dependencies         5.35
    Average incoming package dependencies       1.9
    Average outgoing package dependencies       3.35

Complexity
    Average Cyclomatic complexity by class      1.52
    Average Weighted method count by class      3.43
    Average Relative system complexity          33.29
    Average Difficulty                          2.08

Bugs
    Average bugs by class                       0.02
    Average defects by class (Kan)              0.18

Violations
    Critical                                    0
    Error                                       1
    Warning                                     32
    Information                                 1
~~~

数字の見方、高いほうがいいのか低いほうがいいのか、そもそもどういう指標なのか、といったことがさっぱりわからなかったので、色々と調べてメモしつつ、以下にまとめてみました。基本的に日本語の資料が出てこないので悲しい。ググり方が悪いのか？？

途中、面倒になった箇所はサボっています。

# PhpMetrics 実行結果に表示される指標
## LOC
### lines of code
ソースコード行数。

- LOC が大きいから悪いわけでもないし、小さいから良いわけでもない。（当たり前だが）

### logical lines of code
コメントを除いたソースコードの行数、だと思われる。

- 手元にあるいくつかのプロジェクトで計測してみたところ、どの場合でも
(logical lines of code) + (comment lines of code) =（lines of code）
となっていたので、たぶんあってる。

### comment lines of code
コメントの行数。

- 個人的には、ソースコード内のコメントが少なければ少ないほどよいと思っている（そもそもコメントが必要になるようなコードを書かないほうがえらい）
- しかし、PHPの構文上サポートされていない型に関する記述（特に配列の要素の型）や各種のアノテーションなど、クラスコメント、メソッドコメントは必要に応じて積極的に書いていくべきですよね。
- psalmなどの静的解析が出す警告に対しての対処など、書くべきものは書いていきましょう。

### Average volume
volume の平均。

- volume は、たぶんHalstead complexity measuresのVolume。
- ざっくりソースコードの「仕事量」みたいな感じだと思う。
- volumeの平均の数値を単体で見てもあまり意味がないんじゃない？
- volumeが極端に大きいクラスはリファクタリングした方がいいかも？

- ソースコードの量と複雑さを加味した指標っぽい。
    - 量は、Program length。演算子の数（the total number of operators）とオペランドの数（the total number of operands）の和。
    - 複雑さは、Program vocabulary。演算子の種類数（the number of distinct operators）とオペランドの種類数（the number of distinct operands）の和
    - Volumeは、Program length　× log2(Program vocabulary) 
    - つまり、Volumeは、Program lengthに比例する。
    - つまり、Volumeは、Program vocabularyが増えるとちょっと増える。※log2(Program vocabulary)に比例する。

定義については、以下を参照。
https://github.com/phpmetrics/PhpMetrics/blob/master/doc/metrics.md
https://www.verifysoft.com/en_halstead_metrics.html#32

### Average comment weight
未確認。

### Average intelligent content
未確認。

### Logical lines of code by class
クラスごとの、コメントを除いた行数（多分）

### Logical lines of code by method
メソッドごとの、コメントを除いた行数（多分）

## Object oriented programming
### Classes
クラス数
### Interface
インターフェース数
### Methods
メソッド数。
### Methods by class
Classes ÷ Methods 

### Lack of cohesion of methods
直訳するとメソッドの凝集性の欠如、となる。

> Lack of cohesion of methods (LCOM) is a measure of the number of responsabilities of class.
Thus, if you consider the SOLID principles, the ideal LCOM is LCOM=1.
（適当訳）Lack of cohesion of methods (LCOM) は、クラスが持つ責任の数を示す指標である。
したがって、単一責任の原則を考慮するのであれば、理想的なLCOMの値は1となる。
https://www.phpmetrics.org/documentation/how-to-understand-metrics.html

- 「凝集度が高い」=「すべてのインスタンス変数がすべてのメソッドから使われている状態」
- 前述の通り、クラスの責務が1つだよ、という状態を理想とするなら1になるのがよい。
- ただ、責務のサイズが大きい場合もあるよなー、とは思う
- リファクタリングするべきかどうかの指標、として扱うのが良いのだろう。

下記もあわせて参考

https://iwamototakashi.hatenadiary.jp/entry/20090530/p1


## Coupling
### Average afferent coupling
incoming。どれくらい他のパッケージから参照されているか。責任の大きさ。

> Afferent Couplings (Ca): The number of classes in other packages that depend upon classes within the package is an indicator of the package's responsibility. Afferent = incoming.
（適当訳）Afferent Couplings : 他のパッケージから参照されるクラスの数は、パッケージの責任の度合いを示すindicatorで～す。
https://github.com/phpmetrics/PhpMetrics/blob/master/doc/metrics.md

### Average efferent coupling
outgoing。どれくらい他のパッケージを参照しているか。依存の大きさ。

> Efferent Couplings (Ce): The number of classes in other packages that the classes in the package depend upon is an indicator of the package's dependence on externalities. Efferent = outgoing.
（適当訳）
Efferent Couplings : パッケージ内のクラスが参照する外部パッケージのクラス数は、パッケージの依存の度合いを示すindicatorでーす。
https://github.com/phpmetrics/PhpMetrics/blob/master/doc/metrics.md

### Average instability
不安定性。
Instability = Efferent couplings ÷ （Efferent couplings　+　afferent coupling）

> This metric is an indicator of the package's resilience to change
(適当訳) この指標は、パッケージの変更に対するresilience を示すindicatorでっす
> The range for this metric is 0 to 1, 
この指標は0から1の範囲やで
> with I=0 indicating a completely stable package
この指標が0っちゅうことは、完全にstableやで
> and I=1 indicating a completely unstable package.
逆に、この指標が1ちゅうことは、完全にunstableやで
https://en.wikipedia.org/wiki/Software_package_metrics


### Depth of Inheritance Tree
未確認。

## Complexity
### Average Cyclomatic complexity by class
クラスごとに計測した循環的複雑度の平均値。

- Cyclomatic complexity(循環的複雑度) については、ググれば色々と出てくるので詳細は割愛。
- 大雑把には、分岐とループが多ければ数値が大きくなる。（確か、ネストしてるとめっちゃ増える）
- 当然、低ければ低いほど単純な構造であることを示す。
- 経験的に、この指標はコードのメンテナンス性に大いに関わると思うよ。
- phpmdなどで閾値を設定して、一定以下の循環的複雑度でなければコミットできないようにしておくと良い。
- 認知的複雑度という指標も併用するとよい。確かCodeClimateで計測できる。
- 認知的複雑度が一定の閾値を超える場合にアラートを出す、ってのもできる。（PHPCSを使う）

### Average Weighted method count by class
未確認。

### Average Relative system complexity
システムの複雑さ。
数値が高いほど、問題が発生する可能性が高いことを示唆する。

Relative system complexityの定義（面倒なので英語のまま）

> Fan-out = Structural fan-out = Number of other procedures this procedure calls
v = number of input/output variables for a procedure
(SC) Structural complexity = fan-out^2
(DC) Data complexity = v / (fan-out + 1)
https://github.com/phpmetrics/PhpMetrics/blob/master/doc/metrics.md#card-and-agresti-metric

> RSYSC = average (SC + DC) over all procedures.
http://grahamberrisford.com/AM%202%20Methods%20support/10ComplexityAndAgility/Measures%20of%20size%20and%20complexity.htm

なので、この指標を下げるには

- 呼び出すメソッドの数を減らす
- 入出力する変数の数を減らす

をやればよい。


> Relative system complexity (RSYSC)
Card & Agresti defined system design complexity as composite measure of complexity inside procedures and between them.
It measures the complexity of a system design in terms of procedure calls, parameter passing and data use.


> ・measures the average complexity of procedures in a system.
> システム内の処理の複雑さの平均を示す。
> ・does not depend on the system size.
> システムのサイズには依存しない。
> ・has been found to be a good predictor of the error rate in a system (a high RSYSC predicts lots of 
> errors per lines of code).
> the error rate in a systemの良い予測因子であることが知られている。（RSYSCの値が高いと、1行ごとのエラー発生数がいっぱいだぜ？）


http://grahamberrisford.com/AM%202%20Methods%20support/10ComplexityAndAgility/Measures%20of%20size%20and%20complexity.htm


### Average Difficulty
- たぶん、Halstead complexity measures のDifficulty
- （the number of distinct operators ÷ 2）× (the total number of operands ÷ the number of distinct operands）
- 何を示しているのかはいまいちよくわからんが、低いほうが良いんだろうなー、という感じ

## Bugs
### Average bugs by class
未確認。
コードの複雑さから予測されるバグ数？

### Average defects by class (Kan)
未確認。
コードの複雑さから予測される不具合件数？

# 暫定結論
とりあえず

- Lack of cohesion of methods
- Average Cyclomatic complexity by class
- Average Relative system complexity

あたりを継続的に見ていけば良いんじゃねーかなー、としておく


# メモ、参考情報、課題とか
## 対数について
対数ってよくわからないですよね（高校の数学を完全にサボったため）
計算式の中にlogが出てくると、急によくわからなくなる。感覚的に数字の意味が捉えにくくなるというか。

https://math-jp.net/2018/12/01/taisu-kantan-wakariyasuku/

こういう説明はありがたいですね。log2(x)は、2進法にしたときの桁数、と考えれば良いのか。なるほど

## 実際、どれくらいの値になってれば品質が高いと判断できるの？
- この数字実際どうなん？がよくわからない。
- いろいろなプロジェクトで計測して、プロジェクト間で比較したりしてみないと勘所が見えんのだろうなー