Martinのオブジェクト指向設計メトリクス

コードの品質のスカウターをどうにか作れないかと考えていて、ソフトウェアメトリクスについて調べている。

古い記事ですが、読んだのでメモ書きする。

Robert Martin, OO Design Quality Metrics. An Analysis of Dependencies

https://linux.ime.usp.br/~joaomm/mac499/arquivos/referencias/oodmetrics.pdf

Instability

パッケージ*1の不安定性 (Instability) I は

I = Ce / (Ca + Ce)

で定義される。ここで、Ca は被依存数 (Afferent Couplings) でパッケージ内のクラス*2に依存しているパッケージ外のクラスの数である。また、Ce は依存数 (Efferent Couplings) でパッケージ内のクラスのうちパッケージ外のクラスに依存しているクラスの数である。

Iは[0, 1]の範囲を取る。I = 0のパッケージは非常に多くのパッケージ外のクラスから依存されていて、最大に安定である。一方、I = 1のパッケージはパッケージ外のクラスから依存されておらず、最大に不安定である。

Abstractness

パッケージの抽象度 (Abstractness) A は

A = パッケージ内の抽象クラスの数 / パッケージ内の総クラス数

で定義されている。

AはIと同様に[0, 1]の範囲を取る。A=0のパッケージは具体的で、A=1のパッケージは抽象的となる。

Distance from the Main Sequence

f:id:fjkz:20160410021038p:plain

安定が良くて不安定が悪いかというとそういうわけではない。安定なパッケージほど抽象度が高くあるべきで、不安定なパッケージは具体的であった方がよい。I と A のバランスがとれているといい。そこで、(I, A) = (0, 1)の点と(1, 0)の点を結んだ直線 (Main Sequence) を引いて、それに乗っているようなパッケージが理想的だと考えられる。

そこで、Main Sequenceからの距離 Dをパッケージを評価するときの指標としたい。I, Aが与えられた時に、Main Sequenceからの距離 D は

D = | A + I - 1 | / sqrt(2)

となる。Dは[0, 0.707...]の範囲を取るので、[0, 1]の範囲になるように規格化して | A + I - 1 |としてもいいだろう。これをDnとする。Dn = 0となるような設計が理想的で、Dn = 1のときは非常に悪い設計と言える。

Dn = 1となるのは、(I, A) = (0, 0)のときか(I, A) = (1, 1)のときである。前者の場合は、具体的なクラスが多くのクラスから依存されているので良くない設計となる。後者の場合は、無意味に抽象的なので良くない設計となる。

ノート

  • コンセプトは分からんでもないが、測るのは無理だろう。
  • 不安定性は他のパッケージによって決まる値なので、コントロールできる値ではない。また、この値は変化しうる。
  • 抽象度の定義はもっとよい定義がありそう。
  • 具体はどこのパッケージにあることを想定しているのか。
  • Main Sequenceにあることが本当に理想なのだろうか。抽象度の低い安定なパッケージが有益な場合も多い。そうでないと標準ライブラリは使えない。

*1:元はClass Categoryと書かれている。再利用するときは同時に再利用されるようなクラスのグループのこと。Javaではパッケージに相当すると思われるのでパッケージとする。

*2:ここでのクラスは全てpublicクラスになるかな?