はじめに.
Javaパッケージ単位でメトリクス計測するにはJDependが使える.
JDependは次のメトリクスを計測する.
- 抽象クラスの数(AC: Abstract Classes)
- 具象クラスの数(CC: Concrete Classes)
- 1パッケージに依存する他パッケージの数(Ca: Afferent Couplings)
- パッケージが依存する他パッケージの数(Ce: Efferent Couplings)
- 抽象度合(A: Abstractness )
- 不安定性(I: Instability)
- 距離(D: Distance)
Afferent Couplings
Ca値. この値が大きいほど当該パッケージが他パッケージから参照されている.
Ca値の高いパッケージに対する変更は他パッケージへの変更波及性が高くなる傾向にある.
Efferent Couplings
Ce値. この値が大きいほど当該パッケージが他パッケージを参照している.
Ce値の高いパッケージは他パッケージの変更による影響を受けやすい傾向にある.
Abstractness
A値. 当該パッケージが内包する抽象クラスorインタフェースの度合い.
A = AC / (AC + CC)
で求められる.
A値の高いパッケージは外部への変更波及性が小さくなる傾向にある.
もう1つの観点として, 当該パッケージのCa値が低い場合, 抽象度を高くする必要性は低いと言える.
Instability
I値. 当該パッケージの不安定度合い. 当該パッケージが変更を必要とされる頻度である.
I = Ce / (Ce + Ca)
で求められる.
I値が大きい程, 他パッケージに依存しており, I値が低い程, 他パッケージから依存されていることを
意味する.
この値が大きい程, 外部の変更による影響を受けやすく, 当該パッケージも変更が必要となりやすい傾向にある.
この値が小さい程, 外部に与える影響が高いため当該パッケージの変更には注意する必要がある.
Distance
D値. 当該パッケージが他パッケージとどの程度隔離されているかの度合い.
D = abs((A + I) - 1)
で求められる.
メトリクス計測ではこのD値が重要な指標となる.
いくつかのメトリクスを見てみる.
A = 0, I = 1, Ce = 8, Ca = 0
パッケージの抽象可はされていないものの, Caが0であるため変更波及性は低く, このパッケージは変更しやすい.
D値は0となり, パッケージの状態は良好といえる.
A = 0.4, I = 0.6, Ce = 3, Ca = 2
不安定性がやや高いものの, 抽象度合いも確保されているため, 外部に与える影響は少なく済む.
D値は0となり, パッケージの状態は良好といえる.
A = 0, I = 0.2, Ce = 1, Ca = 4
全く抽象化されていないパッケージ. Ca値が高く外部からの依存度合いも高い.
そのため, 当該パッケージを変更することによる変更波及性は高くなってしまう.
D値は0.8となり, パッケージの状態は悪いといえる.
A = 0.6, I = 1
当該パッケージは外部から依存されていないにも関わらず抽象度合が高いことを示す.
D値は0.6となり, パッケージの状態は改善の余地があるといえる.
一般的に, 依存されている度合い(Ca値)の高いパッケージは抽象度を高くする方が好まれる(.結果, D値が低くなる)
Gradle
apply plugin: 'jdepend'
task(jdepend, type: JDepend) {
classesDir = file('build/intermediates/classes/debug/')
reports {
xml.enabled false
text.enabled true
}
}