2

では、次のフットボール クラブをモデル化しているとしましょう。すべての人は個人です。プレーヤーは人であるため、個人を拡張します。メンバーは個人であるため、個人を拡張します。

スーパークラス:

Individual {name, eyeColour}

サブクラス:

Player extends Individual {position}
Member extends Individual {subscription}

トムはフットボール クラブのオーナーです。

Individual i = new Individual("Tom", "Blue")

ボブとトニーはプレイヤーです:

Player p1 = new Player("Bob", "Green", "Goalkeeper")
Player p2 = new Player("Tony", "Blue", "Striker")

スティーブはメンバーです:

Member m = new Member("Steve", "Brown", 5.00)

個人、プレーヤー、およびメンバーはすべて、Objectify を使用して GAE データストア内の同じ種類 (個人) に永続化されます。

    名前 eyeColor ポジション サブスクリプション ^d
    トム・ブルー [行方不明] [行方不明] 個人
    ボブ グリーン ゴールキーパー [行方不明] 選手
    トニー ブルー ストライカー [行方不明] 選手
    スティーブ ブラウン [行方不明] 5.00 メンバー

たとえば、ボブがプレイヤーだけでなくメンバーになることを決定した場合はどうなりますか? 保存したいのはサブスクリプションです。Bob を個人にアップキャストしてからメンバーにダウンキャストすることはできません。Java はこれを許可しません。新しいメンバーを作成して、ボブのプレーヤー オブジェクトのすべてのプロパティをコピーし、同じ ID で保存することができません。ボブの位置プロパティが失われます。ボブがデータストアのメンバーとプレーヤーの両方である必要がありますが、オブジェクト形式ではありません (私は多重継承の後ではないです)。 (Member.class,"Bob") であり、Member オブジェクトを持っています。位置とサブスクリプションの両方のプロパティを同時に持つオブジェクトは必要ありません。

また、これを避けたいのはデータストアです:

    名前 eyeColor ポジション サブスクリプション ^d
    トム・ブルー [行方不明] [行方不明] 個人
    ボブ グリーン ゴールキーパー [行方不明] 選手
    ボブ・グリーン [行方不明] 10.00 メンバー
    トニー ブルー ストライカー [行方不明] 選手
    スティーブ ブラウン [行方不明] 5.00 メンバー

Bob の名前と eyeColour のデータが重複しているため、データの不一致が生じる可能性があります。

これをモデル化する方法についてのアイデアはありますか?

また、トムがプレイヤーになったり、スティーブがメンバーになったりしたらどうしますか?

4

6 に答える 6

5
Individual {name, eyeColour}
MemberRole {individual, position}
PlayerRole {individual, subscription}

継承があなたのタスクに適していないことは明らかです。たとえば、誰かが 2 つの異なるチームでプレーしたり、2 つの異なるクラブのメンバーになったりする場合があります (元の構造では、複数のサッカー クラブを持つことはまったく許可されません)。

個人が何であるか、そして彼らがどのような役割を持っているかは別のものです。たとえば、一部のグローバル DB で、名前、stackoverflow ポイント、婚姻状況、職業をすべて同じIndividualテーブルに格納することは望ましくありません。

Bob がメンバーになることを決定した場合、Bob 自体は変更されません。その役割はそうです。メンバーになることを決めたボブは、今でも同じ古き良きボブです。以前は禁止されていたことができるようになっただけです。

PS:回答ではサブスクリプションという用語を使用しています。それがあなたのPlayerとは、つまりSubscriptionです。Subscriptions は明らかにIndividuals の特定のサブセットではなくSubscription、完全に異なるエンティティです。もちろん、自分Individualが何に属しているかを知っている必要がありますが、自分自身ではありませんIndividual

于 2012-06-28T08:57:02.613 に答える
3

最初は全員を と見なしIndividualますが、特定の個人を か か のいずれかにする必要Playerがあります。を使用してこのシナリオをモデル化する必要があります。私は Java に詳しくないので、次のコードに似たものを実行することをお勧めします。MemberbothInterfaces

interface IPlayable {void MakePlayable (string position)};
interface IMembership {void AddMembership (double subscription)};

class Individual implements IPlayable, IMembership{name, eyeColour, IPlayable.MakePlayable(string position), IMembership.AddMembership(double subscription)};

//Usage to make Tom a Player
Individual tom = new Individual("Tom", "Blue");
tom.MakePlayable("GoalKeeper");

//Usage to make Steve a Member
Individual steve = new Individual("Steve", "Brown");
steve.AddMembership(5.00);

//Usage to make Jim both a Player and a Member
Individual jim = new Individual("Jim", "Black");
jim.MakePlayable("Forward");
jim.AddMembership(4.00);

複数のインターフェイス シナリオを実装する以外に、ここではインターフェイスを使用することも必要です。Member クラスを使用すると、個人が特定のクラブの永久会員になるためです。IMembership インターフェイスを使用すると、必要なときRemoveMembership()にメンバーシップを削除するのに役立つメソッドを追加できます。Individual将来は。

于 2012-06-28T09:01:53.640 に答える
0

これを試して...

個人はスーパークラスになります

インターフェイスとしてのプレーヤーとメンバー

ボブをプレーヤーおよびメンバーとして想定します。

今..

ボブは個人です(つまり、個人を拡張します)

ボブはプレーヤーとメンバーのインターフェイスを実装します(つまり、ボブはプレーヤーとメンバーの両方の役割を果たします)

于 2012-06-28T09:04:13.563 に答える
0
public class Individual {
    Role role;
    int    position;     //empty for MEMBER,filled for PLAYER_MEMBER and PLAYER
    int    subscription; //empty for PLAYER,filled for PLAYER_MEMBER and MEMBER }

public enum Role {  MEMBER,PLAYER,PLAYER_MEMBER; }

したがって、切り替えが完了したら、ロールを変更して不足しているフィールドを完成させるだけです。検証を行う必要があります。

于 2012-06-28T09:27:54.907 に答える
0

GAE ドキュメントのJDO でのエンティティ関係を参照してください。

オブジェクト タイプのフィールドを使用して、永続オブジェクト間の関係をモデル化できます。永続オブジェクト間の関係は、オブジェクトの 1 つが他のオブジェクトなしでは存在できない所有されている、または両方のオブジェクトが相互の関係とは無関係に存在できる非所有として記述できます。JDO インターフェースの App Engine 実装は、所有および非所有の両方の 1 対 1 の関係と、単方向および双方向の両方の 1 対多の関係をモデル化できます。

あなたには 2 つの「所有」関係があると思います。Player両方とも をMember「所有」していIndividualます。

于 2012-06-28T09:10:19.940 に答える
0

クラス Indiviual (name, eyecolor) を作成し、Owner、Player、Member のインターフェイスを作成します。あなたはユニークな個人を持ち、それらに機能を追加し続けます. したがって、必要に応じてテーブルが作成され、最後の列にはさまざまな実装がリストされます。

インターフェイスを使用することは、多重継承を実装するよりもはるかに優れており、java はこれを行います。だから、これを使うのが一番いい

于 2012-06-29T10:35:17.750 に答える