1

私のアプリケーションの設計では、 と の 2 つのクラスがあるPersonとしCompanyます。また、 と の間の 1 対多の関係を定義する UML ダイアグラムを定義した PersonとしますCompany。すべてのPersonオブジェクトは 1 つの だけに属する必要がCompanyあり、 には複数のCompanyを含めることができますPerson

この単純な制約が常に保持されるようにするためのベスト プラクティスは何PersonですかCompany? 私は3つのアプローチを考えました:

  1. 私の制約に決して違反しない、完璧でバグのないコードを用意してください。ただし、現実主義者として、特に制約の数が増えるにつれて、これが困難または不可能であることを私は知っています。

  2. ensureCorrectness()すべての制約を手動でチェックするメソッドを実装します。この例では、すべての をループし、 1 つだけにそのが含まれてPersonいることを確認します。そうでない場合は、エラーが出力されます。私はこのメソッドを頻繁に呼び出します。CompanyPerson

  3. たとえば、Hibernate を使用してデータベース スキーマを定義し、データをデータベースに保存します。スキーマでは、UML 図の制約と一致するように制約を定義できます。次に、データをデータベースに永続化するたびに、Hibernate はすべての制約をチェックし、問題が発生した場合はエラーを出力します。

しかし、(1) 完全性、(2) 手動検証、または (3) リレーショナル データベースに依存しない、Java でこれを行うための別のよりクリーンな方法があるかどうか疑問に思わずにはいられません。次のようなコードで注釈を指定できるライブラリまたはフレームワークはありますか。

@OneToMany(Person, Company)

または、より具体的には次のようになります。

@OneToMany(Person, Company.persons)

CompanyクラスにList<Person> personsメンバー変数があると仮定します。

また、個人の社会保障番号がすべてPersonの s で一意であることを確認したい場合は、次のように言えます。

@Unique(Person.SSN)

このようなものはJavaに存在しますか?

4

4 に答える 4

0

企業と個人の関係は難しくありません。たとえば、Company に含まれる Person 要素のリストを作成します。手動で確認する必要があることの 1 つは、リストに単一の Person の複数のインスタンスが含まれていないことです。

その逆はもっと難しい。これを手動で確認する必要があります (各リストに同じ人物の複数のインスタンスが含まれていないこと)。ただし、前の制限と組み合わせることができます。

人物のすべてのリストの長さは、一意の人物を含むすべてのリストの長さと等しくなければなりません。

私はデータベースについてあまり知識がありませんが、2 番目のオプション (ensureCorrectNess) を使用して、上記の手動の制限を確認します。

于 2013-06-07T13:18:36.487 に答える
0

私はJavaでそのように実装します:

public class Company {
    Set<Person> persons;
    ...
    public void addPerson(Person person) {
        if (person.getCompany() != this) { // Avoiding an infinite loop between addPerson() and setCompany()
            person.setCompany(this);
            persons.add(person);
        }
    }
    public boolean removePerson(Person person) {
        return persons.remove(person);
    }
    ...
}

public class Person {
    Company company;
    public Person(Company company) {
        this.company = company;
    }
    public void setCompany(Company company) {
        if (this.company != null) {
            this.company.remove(this);
        }
        this.company = company;
        company.addPerson(this);
    }
    ...
}

コードでは、Personを複数持つことはできず、 のリストを持ちCompanyます。コンストラクターにより、少なくとも 1 つの会社が割り当てられます。CompanyPersonsPerson(Company)Person

編集:(重複なし)を変更するには、メソッドを呼び出すメソッドSetを通過する必要があります。このメソッドは、前のリストからを削除し、新しいリストに追加します。addPerson()Person.setCompany()PersonCompanyCompany

ではsetCompany()、 を呼び出す必要があります。これは、プログラマーが最初に を呼び出すことなく、 aを aaddPerson()に直接代入できるためです。PersonCompanyaddPerson()

于 2013-06-07T13:20:11.540 に答える
0

カプセル化と組み合わせて、私は#1に行きます。このようにして、100% バグをなくす必要があるコードの量は非常に少なくなります。

public class Company {
    private List<Person> persons = new ArrayList<>();
    private List<Person> publicPerson = Collections.unmodifiableList(persons);

    public List<Person> getPersons { return publicPersons; }

    public void addPerson(Person p) {
         ... ensure p is removed from old company
         p.setCompany(this);
         persons.add(p);
    }

}

public class Person {
    private Company company;
    /* pkg-private */ setCompany(Company company) {
        this.company = company;
    }
    public Company getCompany() {
        return company;
    }
}

注意してください、このコードはスレッドセーフではありません!

データベースに保存する場合、hibernate は制約のみをチェックすることに注意してください。キャッシュが原因で、不整合が発生する場合があります。

于 2013-06-07T13:34:03.877 に答える
-1

最初に、データベース内の列をnullではなく、顧客IDを一意に設定することにより、DBでこれらすべてを非常に簡単に構成できます。前後にトリガーを使用して、データが DB から削除または追加されたことを確認できます。

2 番目のオプションでは、ハッシュ マップを使用してデータを含めることにより、すべての DB on Java クラスを設定できます。

私の意見では、最初のオプションはより簡単です..

于 2013-06-07T13:18:16.607 に答える