2

重複のある継承階層があります。システムは、クライアント、プロバイダー、およびエージェントになることができる人物について認識しています。人はこれらのクラスの 1 つに属さなければなりませんが、2 つまたは 3 つのクラスに属することができます。つまり、1 人の人が同時にクライアントとプロバイダーになることができます。

データベースでは、クラスごとに1つのテーブル(Person、Client、Provider、およびAgentテーブル)と、サブクラステーブルのプライマリキーからスーパークラステーブルのプライマリキーへの外部キーで、問題が解決したと思います。(可能な改善は大歓迎です:))

問題は Java の世界にあります。このデータベース設計を Java POJO にマップする最善の方法がわかりません。考えられる厄介な回避策が 3 つあります。

  • サブクラスのすべてのフィールドを結合した、Person という名前の一意のクラス。これには、Person の種類を知るために識別子フィールドが必要です。問題は、クライアントではなくプロバイダーである人物は、クライアント関連のすべてのフィールドが null に設定されることです。

  • サブクラスに共通するすべてのフィールドと、各サブクラスに関連するフィールドを保持する 3 つの「DTO 種類」のプロパティを持つ Person という名前の一意のクラス。このようにして、10 の代わりに 1 つまたは 2 つのフィールドを null にするだけです。

  • Person の 1 つの抽象クラスと 7 つのサブクラス (Client、Provider、Agent、ClientProvider、ClientAgent ... ClientProviderAgent) の 3 つのサブクラスの可能な組み合わせごとに 1 つ。:S(もちろん、対応するインターフェースを持つ全員)

ウェブアプリです。UIにhibernate + springとGWTを使用しています

問題は、この問題を解決する最善の方法はどれかということです。

4

1 に答える 1

11

IMO 継承は、これをモデル化する最良の方法ではありません。代わりに合成を試みます。

Person クラスといくつかの Role クラス (コンテキストに応じて、共通のインターフェイスを実装するか、Role 列挙型のメンバーになる) を作成し、各人に 1 つ以上の Role を関連付けることができます。

このようにして、新しい役割タイプを簡単に追加し、役割を個人に動的にアタッチ/デタッチできます。(必要に応じて、役割を持たない人物を作成することもできます。)

大まかな例:

interface Role {
  ...
}

final class Client implements Role {
  ...
}

final class Provider implements Role {
  ...
}

final class Agent implements Role {
  ...
}

class Person {
  List<Role> roles;
  public void addRole(Role role) { ... }
  public void removeRole(Role role) { ... }
  public Role getRoleOfType(Class<? extends Role> roleType) { ... }
}

更新: 列挙型ベースの例

これは、役割オブジェクトに状態がない場合に適用されるため、同じ役割インスタンスをすべての人に関連付けます。

enum Role {
  CLIENT,
  PROVIDER,
  AGENT;
  // possible members, constructor etc.
}

Person クラスは上記とほぼ同じですが、次の点が異なります。

  • これは列挙型用に特別に調整されているため、 のEnumSet代わりにを使用します。List
  • getRoleOfType()ここでは意味がないので、 に置き換えましたhasRole()

    class Person {
      Set<Role> roles = new EnumSet<Role>();
      public void addRole(Role role) { ... }
      public void removeRole(Role role) { ... }
      public boolean hasRole(Role role) { ... }
    }
    
于 2010-09-27T15:45:25.490 に答える