2016-11-20 9 views
8

Javaで記述され、HibernateにマップされたHRアプリケーションを開発します。特徴の1つは募集のフェーズです。私たちはコードがfiscalCodeクラスのプロパティを見て、特定の法律に非常に依存しているだけで、今まで市場向けに開発されているのでOOP - クラスにプロパティを追加するための最善のアプローチ

public class Candidate { 
    private String id; 
    private Integer candidateCode; 
    private GregorianCalendar birthDate; 
    private String italianFiscalCode; //unique code for italian people 
} 

Candidateクラスは、次のようにモデル化されています。

私たちは、この概念を、例えば一意の識別子が異なる可能性があり、いくつかの文字列で構成されていても、全く存在しなくてもよい、他の市場にも拡大できるように一般化しています。私の心にポップ

まず最初:

1 - 単にcountryIdentifierとしてフィールドの名前を変更し、特定の国のために必要に応じて他のフィールドを追加します。

private String countryIdentifier; //general unique code 
private Integer greekAddedCode; 

これは、DBMS列の名前を変更(および最終的に他のものを追加する)、そのフィールドを使用するすべてのクエリを変更する、(古いitalianFiscalCodeが使用されますここですべての配置)に必要なコードをリファクタリングを意味します。

これは

2私には貧しい実装のように見える - サブクラスCandidateItalianCandidateGreekCandidateを作成し、サブクラスで特定のフィールドを移動します。

問題は(私たちは(多対1とセット)すべての「重い」プロパティを移動するので重いクラスでHibernateマッピングを最適化するための唯一の機能を有しているCandidateクラスがすでにHeavyCandidateによってサブクラス化されていることですこれは私たちのすべての豆に従うアプローチです)。

この場合、最も正しいアプローチは何ですか?

+3

を作るための良い方法です。いいえ、候補にはHeavyCandidate型のフィールドが必要です。これは_is__関係ではありません。あなたの現在のアプローチは、継承の重大な濫用であり、継承をこのように悪用してはならない理由の優れた例です。 –

+0

あなたの返信ありがとうございます@BoristheSpider。私はこのアプローチがHibernateを介して簡単にBeanをマップできるようになったと思いますが、正しいものではないと私は同意します。 – frankieta

答えて

0

GreekIdentifierItalianIdentifierのようなクラスで実装されているインターフェイスIdentifier(名前についてはわからない)を作成します。それから私はCandidateにフィールドを追加したい:

Identifier identifier; 

GreekIdentifierの実装は、このようなものになります。countryIdentifierは本当にすべての識別子を持っている何かであるならば、あなたもそれを移動することができます

public class GreekIdentifier implements Identifier { 
    String countryIdentifier; 
    int addedCode; 

    //constructor, getters, setters ... 
    //actual behaviour, Indentifier @Overrides ... 
} 

を基本クラス(抽象クラ​​ス)までです。

+0

Identifierにはどのような方法が含まれていますか?それとも単にマーカーインターフェイスですか? – developer

+0

すべての識別子に共通の動作を含みます。最終結果は何ですか?この情報で何をしたいですか?識別子とは何ですか?私は本当にcountryIdentifiersとコードについて何も知らない... –

+0

トッド、ありがとう、私はそれがCadidateのサブクラス化の問題を避けるより正しいアプローチだと思う。ポイントは、その時点で識別子を格納するために別のテーブルを作成する必要があります。データを取得するために追加された結合が欠点になると確信しています。 – frankieta

0

私にとっては、クラスを拡張してサブクラスを作成するのが最善のことです。

次に、必要なフィールドをそのクラスに追加します。

ので

public class YourCandidate extends Candidate{ 

    // extra fields 
} 

候補と他のGreekCandidatesとの関係マッピングのための別のテーブルを作成します。これを採用することにより

:あなたは、コードの重複を防止するであろう

  1. OOPの主な原則に固執し、階層を維持します。これは良いexampleです。
  2. あなたは現在のクラスとテーブルを変更する必要はありません。、これは常に良いことです。
+0

ありがとうございました。リンクされた記事を読むつもりですが、クラスが既にサブクラス化されているという事実について助言していますか? – frankieta

+0

@frankietaサブクラスを持つ必要があるすべての国のサブクラスを拡張できると思います。 –

+0

HeavyCandidateを延長することを意味しますか?そのクラスは、識別子フィールドと比較してプライマリ情報ではないデータを大量にロードします。 – frankieta

1

これを行うには、抽象クラスを作成するのが良い方法だと思います。これを使用することにより、候補オブジェクトごとに汎用フレームワークが提供され、拡張クラスに特定のメソッドが必要であることも暗示されます。 「_The問題は `Candidate`クラスがすでにHeavyCandidate`_`によってサブクラス化されていることである」これはまた、コンストラクタで動作します、そして、それは一般的なアウトライン

public abstract class Candidate{ 
    //Use Vars Here 
    private String name; 

    //Constructor for the abstract class 
    public Candidate(String n){ 
     //Add Normal Constructor Code Here 
     name = n; 
    } 

    //A possible abstract method that may vary based on the type of candidate 
    public abstract String getType(); //Abstract Methods must be defined in a child class 
} 


public class SpecificCandidate extends Candidate{ 
    //Add other needed vars 
    //Normal Constructor 
    public SpecificCandidate(String n){ 
     super(n);  //This gets passed into the abstract constructor 
    } 

    //Define the Abstract Method 
    @Override 
    public String getName(){ 
     return "Specific"; 
    } 
} 
関連する問題