minimize

事業拡大のため、新しい仲間を募集しています。
→詳しくはこちら

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 の範囲を持ちます。

いくつかのパターンを考えてみます。

A = 0, I = 1

抽象度が0、不安定性が1です。
ここで Ce = 8, Ca = 0 だとしましょう。
つまり、8つのパッケージに依存していて、外部からは全く依存されていない状況です。

外部パッケージが8つもあり、このパッケージに与える影響は大きいですが
外部から全く依存されていないので、自由にこのパッケージを変更することが出来ます。

この場合、D = abs((0 + 1) - 1) = 0 となります。
D は小さい方が良いとされているので、このパッケージが非常に良い設計であるという事です。

A = 0.4, I = 0.6

全10クラスのうち、4つが抽象クラスとなっています。
Ce = 3, Ca = 2としましょう。
3つのパッケージに依存していて、外部2つのパッケージから依存されています。

不安定性はやや高いですが、抽象度も比較的高いので
このパッケージを変更することによって外部に与える影響は少なくて済みます。
また、3つのパッケージにしか依存していないので
外部パッケージの変更による影響も受けにくいのです。
D = 0 という、理想的なパッケージです。

A = 0, I = 0.2

全10クラス全てが実体のある(Concrete)クラスです。
Ce = 1, Ca = 4としましょう。
1つのパッケージに依存していて、外部4つのパッケージから依存されています。

依存されている度合いが高いため、このパッケージを容易に変更することは出来ません。
しかし、全く抽象化されていないので
このパッケージを変更することによって外部パッケージへの影響が
大きく出てしまいます。
D = 0.8 という、あまり良くないパッケージです。

A = 0.6, I = 1

全10クラスのうち、6つが抽象クラスとなっています。
しかしこのパッケージは外部から全く依存されていません。
こういった場合、抽象化することは逆に物事をわかりにくくしてしまいます。

D = 0.6 となり、あまり良いパッケージではありません。
こういったパッケージでは無理に抽象化する必要は無いのです。

以上をふまえて簡単に説明すると、依存されている度合いが高いパッケージは
抽象度を高くした方が良い、という事です。

パッケージ依存関係の循環

あるパッケージAがパッケージBに依存しているとします。
このとき、パッケージBもパッケージAに依存しているとしたら、
これらのパッケージは互いに参照し合っているという事になります。

このようなパッケージ依存関係の循環は、避けるべき状況です。

導入に際して

JDependは非常に高度なパッケージのメトリクスを計測します。
初めのうちはあまり気にする事も無いかもしれませんが
次第にこれらの数値を改善していくことが
コードの質を高めていくという実感が湧いてくるはずです。

まずは手始めに、パッケージの循環依存から改善しましょう。

Limy Eclipse Plugin を使えば、JDependによるメトリクス測定をレポートできます!