LCOM(Lack of Cohesion of Methods)は、クラスの凝縮度を測定する指標です

プロンプト

このクラスを凝縮度(LCOM)が高いクラスにリファクタリングできますか?複数のクラスに分割して構いません。

class Person {
  String name;
  int age;
  String address;

  public void printName() {
    System.out.println(name);
  }

  public void printAge() {
    System.out.println(age);
  }

  public void printAddress() {
    System.out.println(address);
  }
}

ChatGPTの回答

クラスPersonは、名前(name)、年齢(age)、住所(address)といった属性を持つことが明示されています。そのため、それぞれの属性とそれに関連したメソッドを個別のクラスに分割することが可能です。しかし、このようなリファクタリングは、通常はドメインやビジネスロジックに応じて行います。今回のケースでは、名前、年齢、住所といった属性が1つの人間(Person)を表すものであることから、この分割はあまり理に適っていないかもしれません。

それでも、あくまで例示として、下記のようにクラスを分割することができます。

javaCopy codeclass Name {
  String name;

  public Name(String name) {
    this.name = name;
  }

  public void printName() {
    System.out.println(name);
  }
}

class Age {
  int age;

  public Age(int age) {
    this.age = age;
  }

  public void printAge() {
    System.out.println(age);
  }
}

class Address {
  String address;

  public Address(String address) {
    this.address = address;
  }

  public void printAddress() {
    System.out.println(address);
  }
}

class Person {
  Name name;
  Age age;
  Address address;

  public Person(Name name, Age age, Address address) {
    this.name = name;
    this.age = age;
    this.address = address;
  }

  public void printPerson() {
    name.printName();
    age.printAge();
    address.printAddress();
  }
}

このようにクラスを分割することで、それぞれの属性とその操作が個別のクラスに集約され、高い凝縮度(LCOM)を持つようになります。しかし、このような分割はビジネスロジックによっては不適切な場合もありますので、注意が必要です。


今回の例は、あんまり良くないかもよってことなので、ベスプラについても聞いてみる。

プロンプト その2

凝縮度(LCOM)を考える際のベストプラクティスを教えてください。

ChatGPTの回答 その2

凝縮度(Lack of Cohesion in Methods, LCOM)は、クラス内のメソッドがどれだけ共通のデータにアクセスしているか、またはクラス内でどれほど密接に関連しているかを示す指標です。低いLCOMはクラスがうまくまとまっていることを示し、高いLCOMはクラスが関連性の低い属性やメソッドを多く含んでいる可能性があります。

以下は、LCOMを考慮する際のベストプラクティスです。

  1. シングル・レスポンシビリティ・プリンシプル: クラスは一つの責任を持つべきです。シングル・レスポンシビリティ・プリンシプルに従って設計されたクラスは、通常、低いLCOM値を持ちます。
  2. 共通のデータへのアクセス: クラス内のメソッドが共通の属性にアクセスするとき、それは一般的に良い設計とされます。メソッドがクラス内の他のメソッドや属性との連携なしに動作する場合、それらは別のクラスに移動されるべきです。
  3. クラスの分割: LCOMが高い場合、クラスをさらに具体的なサブクラスに分割することを検討してください。これにより、関連する属性とメソッドが同じクラス内に保持され、凝集度が高まります。
  4. 依存関係の最小化: クラスは、できるだけ少ない外部のクラスに依存すべきです。これにより、変更の影響が最小限に抑えられ、LCOMも低く保たれます。
  5. コンポジションを使用: クラスが異なる責任を持つ属性を多く持っている場合、これらの属性を個別のクラスに分割し、元のクラスがこれらの新しいクラスを使用するコンポジションを検討してください。
  6. コードレビューとリファクタリング: ペアプログラミングやコードレビューを通じて、LCOMが高くなる原因を特定し、リファクタリングを行ってください。これには、メソッドの抽出、クラスの分割、インターフェースの使用などが含まれるかもしれません。
  7. 自動化ツールの使用: LCOMを測定するツール(例:SonarQube, JArchitectなど)を使用して、コードの品質を継続的に監視してください。

これらのベストプラクティスは、クラスの設計と整理に役立ち、LCOMを適切な範囲に保ちます。しかし、LCOMは一つのメトリクスに過ぎません。他の要因とバランスを取りながら、プロジェクトの全体的なアーキテクチャと設計を考慮してください。