JDepend は、Javaパッケージ単位のメトリクスを測定するツールです。
これによって以下のような事がわかります。
Afferent Couplings (Ca)
と呼ばれ、この数値が大きいほど
このパッケージは外部から参照されている箇所が多いという意味になります。
つまり、このパッケージの内容を変更することは
外部パッケージに大きな影響を与えることになります。
Efferent Couplings (Ce)
と呼ばれます。先程と全く逆ですね。
この数値が大きいことは、外部パッケージの変更が
このパッケージに大きな影響を与えることを意味します。
パッケージに属する全クラスのうち、抽象クラスもしくはインターフェイスの割合をAbstractness (A)
と呼んでいます。
この値が大きくなると、パッケージの実装を変更しても
インターフェイスを変えない限り、外部へ与える影響は少なくなります。
逆に、外部から全く参照されていないパッケージの場合
抽象度を高くするメリットはありません。
やや難しい概念ですが、Instability (I)
と呼ばれています。I = Ce / (Ce + Ca)
という計算式で求められます。0 ~ 1 の範囲を持ちます。
この値が大きいことは、このパッケージは外部に依存する割合が高いということを意味します。
例えば、このパッケージに依存するパッケージ(Ca)が1、
このパッケージが依存するパッケージ(Ce)が5としましょう。
この場合、I = 5 / (5 + 1) ≒ 0.83 となり、このパッケージは不安定性が高いことになります。
外部に多く依存しているため、それらのパッケージが変更される度に
このパッケージも変更しなければなりません。
逆にこの値が小さい場合、このパッケージは外部から依存される割合が高いということを意味します。
例えば、このパッケージに依存するパッケージ(Ca)が5、
このパッケージが依存するパッケージ(Ce)が1としましょう。
この場合、I = 1 / (1 + 5) ≒ 0.17 となり、このパッケージは不安定性が低いことになります。
外部から多く依存されているため、このパッケージは迂闊に変更できません。
不安定性とは「今後どれだけ変更の可能性が高いか」と考えればわかりやすいかもしれません。
ここが JDepend の肝となる大事な部分です。D = abs((A + I) - 1)
の式で表されます(absは絶対値を求める関数)。
0 ~ 1 の範囲を持ちます。
いくつかのパターンを考えてみます。
抽象度が0、不安定性が1です。
ここで Ce = 8, Ca = 0 だとしましょう。
つまり、8つのパッケージに依存していて、外部からは全く依存されていない状況です。
外部パッケージが8つもあり、このパッケージに与える影響は大きいですが
外部から全く依存されていないので、自由にこのパッケージを変更することが出来ます。
この場合、D = abs((0 + 1) - 1) = 0
となります。
D は小さい方が良いとされているので、このパッケージが非常に良い設計であるという事です。
全10クラスのうち、4つが抽象クラスとなっています。
Ce = 3, Ca = 2としましょう。
3つのパッケージに依存していて、外部2つのパッケージから依存されています。
不安定性はやや高いですが、抽象度も比較的高いので
このパッケージを変更することによって外部に与える影響は少なくて済みます。
また、3つのパッケージにしか依存していないので
外部パッケージの変更による影響も受けにくいのです。
D = 0 という、理想的なパッケージです。
全10クラス全てが実体のある(Concrete)クラスです。
Ce = 1, Ca = 4としましょう。
1つのパッケージに依存していて、外部4つのパッケージから依存されています。
依存されている度合いが高いため、このパッケージを容易に変更することは出来ません。
しかし、全く抽象化されていないので
このパッケージを変更することによって外部パッケージへの影響が
大きく出てしまいます。
D = 0.8 という、あまり良くないパッケージです。
全10クラスのうち、6つが抽象クラスとなっています。
しかしこのパッケージは外部から全く依存されていません。
こういった場合、抽象化することは逆に物事をわかりにくくしてしまいます。
D = 0.6 となり、あまり良いパッケージではありません。
こういったパッケージでは無理に抽象化する必要は無いのです。
以上をふまえて簡単に説明すると、依存されている度合いが高いパッケージは
抽象度を高くした方が良い、という事です。
あるパッケージAがパッケージBに依存しているとします。
このとき、パッケージBもパッケージAに依存しているとしたら、
これらのパッケージは互いに参照し合っているという事になります。
このようなパッケージ依存関係の循環は、避けるべき状況です。
JDependは非常に高度なパッケージのメトリクスを計測します。
初めのうちはあまり気にする事も無いかもしれませんが
次第にこれらの数値を改善していくことが
コードの質を高めていくという実感が湧いてくるはずです。
まずは手始めに、パッケージの循環依存から改善しましょう。