PMD などの静的解析ツールで、God Class(ゴッドクラス)という警告が出ることがあります。
Possible God class (WMC=52, ATFD=76, TCC=0.022058823529411766).
God Class は、本来あまり関連性を持たせるべきではない多くのクラスを参照、結びつけてしまっているクラスであり、神のように全体を制御しているクラスを指します。 クラスの責務分割がうまくいっていない場合に、このような多くの責務を持つクラスができてしまうことがあります。 上記の警告が出た場合は、クラス内の処理を適切なまとまりで別のクラスに分割する、といったリファクタリングが必要であることを示唆しています。
あるクラスが God Class になっているかどうかを定量的に判断できるようにした WMC、ATFD、TCC というメトリクスが、Michele Lanza と Radu Marinescu の Object-Oriented Metrics in Practice で紹介されています。
これらの値が、下記の条件をすべて満たすと、God Class とみなされます。
それぞれのメトリクスは、下記のような意味を持っています。
WMC は、クラス内のメソッドの複雑度の合計値です。 WMC が高いということは、アプリケーションへの依存度が高く、再利用性、メンテナンス性の悪いクラスであることを示します。 逆に、WMC が低いということは、明示的な分岐などが少なく、オブジェクト指向における多態性(ポリモーフィズム)を活かした設計ができているクラスと言えます。 複雑度の計算方法は色々あるようです。
PMD のコードを見る限り、1 番の Cyclomatic Complexity が採用されており、下記のような要素の合計値で求められるようです。
if
、while
、for
、switch
のラベル、catch
、?
など)||
) や AND (&&
) の数メソッド数や分岐の数が増えると、WMC の値も単純に 1 つずつ増加していくと考えればよさそうです。
他のクラスのオブジェクトの属性を、直接参照している個所の数です。PMD では、get
や is
、set
などで始まるメソッドを呼び出している箇所もカウントされるようです。
ATFD の値が大きいということは、他のオブジェクトの構造に強い依存があることを示しており、独立して変更することが難しいことを意味します。
オブジェクト間のコミュニケーションを、論理的なメソッド経由で行うようにすることで、別のクラスの構造に対する直接的な依存度を下げることができます。
TCC は 0 ~ 1 の範囲の数値で、メソッドの凝集度(メソッド同士の関連性がどの程度あるか)を表しています。 TCC が低いということは、関連性の低いメソッドが 1 つのクラスに入っており、複数の責務が混ざってしまっていることを示唆しています。
TCC は、visible なメソッド(private 以外のメソッド)に対して、下記のような計算を行うことで求められます。
直接接続されたメソッドの関連の数 / メソッドの関連の合計数
「直接接続されている (directly connected)」とは、2 つのメソッドにおいて、それぞれメソッド呼び出しを辿っていったときに、同じメンバ変数を参照していることを示します。
たとえば、メソッド A と、メソッド B が、同じメンバ変数を参照していれば、A と B は directly connected ということになり、上記の式における分子が +1 されます。メソッド A、B、C が同じメンバ変数を参照していれば、関連の数は 3 となります(A ⇔ B、B ⇔ C、C ⇔ A が directly connected な関連となる)。
一方で、分母の「関連の合計数」は、単純に visible なメソッドの関連の数であり、メソッド数を n
として、n (n - 1) / 2
という計算で求められます。
このあたりの関連の説明に関しては、このサイトの説明がとてもわかりやすいです。
TCC が低すぎるということは、関連のない内部データにアクセスするメソッドが多いということを示しています。 それはすなわち、クラスを適切な責務ごとに分割すべきであることを示しています。