コーディングでクラス分けをする際、クラスはランダムに分けるのでなく何かを基準にして分けるべきです。自分の場合、コーディング規約(明文化されていないフレームワークのおすすめ方法とか含めて)に沿うことを前提として役割、想定する実体あたりを基準にしています。
何を基準にして分けるにしろ適切に分けられたならば、分けられ作られたプロパティ、メソッドはまとまっており、関連性が出てきます。凝集度とはこの関連性の度合いのことであり、LCOM(Lack of Cohesion in Methods)は具体的に凝集度を数値化した時の指標の一つです。LCOMは次の式で表されます。
前半のAほにゃららはメソッドがアクセスするプロパティ数の平均になります。そのためこの部分の値は0からMをとります。またMのみが極大の時、Aのみが極大の時にLCOM=1になります。
要はLCOMが0に近づくほどプロパティの数に対してプロパティにアクセスするメソッドの数が多く、LCOMの値が大きくなるほどプロパティを無視しているメソッドが多い、ということです。LCOMは 1 – (sum(a) / (M * A))や(M * A) / sum(a)などいくらか変形がありますが、プロパティとメソッドの数とプロパティにアクセスするメソッドの数の比率から求められる値であり、小さいほど良い値であることは共通して作られています。
LCOMが真価を発揮するのはクラスの使い方が、あるオブジェクトの情報を持ち、そのオブジェクトに対しての操作メソッドをまとめる、という時です。この時LCOMが小さい程そのクラスは一つのオブジェクトに関する情報と動作の操作に専念しているといえます。とても凝集しているわけですね。
LCOMはいい指標ですが適切な設計であっても悪い値になる時があります。それは疎な情報を持つオブジェクトを扱う時です。例えばデータベース中のテーブルのカラムを全てオブジェクトのプロパティに取り込んだ時、プログラムで触らないカラムが現れることがあります。そういった時、オブジェクトを正確に反映したクラスであってもLCOMの値は悪くなります。
またLCOMの値を良くすることを目的そのものとしてはいけません。LCOMは凝集度を評価するための値であり、凝集度もクラスの中のプロパティ、メソッドのまとまり具合の度合い、結局はクラスの良さそのものではありません。極端な話、メソッドで参照するのみの意味のないプロパティを大量に持たせ、都度呼び出せばLCOMは良い値にできてしまいます。その様なクラスが良いクラスなわけがありません。LCOMはコードの評価の一側面として扱うのがいいでしょう。