繁体   English   中英

如果不是多态,我该如何为这些类建模

[英]If not polymorphism, how do I model these classes

好吧,我说我正在为以下足球俱乐部建模:所有人都是个人。 玩家是一个人,因此扩展个人。 会员是一个人,因此扩展个人。

超类:

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数据库中的同一种(个体)。

name    eyeColour   position        subscription    ^d
    Tom     Blue        [missing]       [missing]       Individual
    Bob     Green       Goalkeeper      [missing]       Player
    Tony    Blue        Striker         [missing]       Player
    Steve   Brown       [missing]       5.00            Member

如果Bob决定成为会员以及玩家怎么办? 我想存储是订阅。 我无法将鲍勃贬低为个人,然后向成员倾斜。 Java不允许这样做。 我无法创建新成员并复制Bob的Player对象的所有属性并将其存储回相同的ID - 我将失去他的Position属性。 我需要Bob成为数据库中的成员和播放器,但不是对象形式(我不是在多重继承之后)我仍然希望获得(Player.class,“Bob”)并拥有一个Player对象或获取(Member.class,“Bob”)并有一个Member对象。 我不需要同时具有位置和订阅属性的Object。

我也想避免这是数据存储区:

name    eyeColour   position    subscription    ^d
    Tom     Blue        [missing]   [missing]   Individual
    Bob     Green       Goalkeeper  [missing]   Player
    Bob     Green       [missing]   10.00       Member
    Tony    Blue        Striker     [missing]   Player
    Steve   Brown       [missing]   5.00        Member

因为Bob现在在名称和eyeColour上有数据重复,这可能导致数据不一致。

有关如何建模的任何想法?

如果汤姆成为一名球员,或者史蒂夫成为会员呢?

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

很明显,继承不适合您的任务。 例如,某人可能会在两个不同的球队中比赛,或者是两个不同俱乐部的成员(并且您的原始结构将不允许拥有多个足球俱乐部)。

个人是什么,他们有什么角色,是不同的事情。 例如,您不希望某个全局数据库在同一Individual表中存储您的姓名,您的stackoverflow点,您的婚姻状况和您的职业。

如果鲍勃决定成为会员,鲍勃本身不会改变; 它的角色呢。 鲍勃决定成为一名成员仍然是同样优秀的老鲍勃,只是他现在能够做一些他早先被禁止的事情。

PS:您在答案中使用的是“ 订阅 ”一词。 这就是你的播放器 - 订阅 Subscription显然不是Individual的某些特定子集, Subscription是完全不同的实体。 当然,它应该知道Individual所属的是什么,但它本身并不是Individual

一开始我会把每个人视为Individual ,但你想让某些人成为PlayerMemberboth 您需要使用Interfaces为此场景建模。 由于我不是Java,我建议做类似于这段代码的事情:

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将来需要的时候。

尝试这个...

个人是SuperClass

播放器和成员作为接口

假设Bob是玩家,也是会员。

现在..

鲍勃是个人(即扩展个人

Bob 实现播放器和成员接口 (即Bob播放播放器和成员的角色)

请参阅GAE文档中的JDO中的实体关系

您可以使用对象类型的字段来建模持久对象之间的关系。 持久对象之间的关系可以被描述为拥有,其中一个对象在没有另一个对象的情况下不能存在,或者是无主对象,其中两个对象可以独立于彼此的关系而存在。 JDO接口的App Engine实现可以模拟自有和非拥有的一对一关系以及一对多关系,包括单向和双向关系。

我会说你有两个“拥有”的关系。 PlayerMember都“拥有”的Individual

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; }

因此,当切换完成后,您只需更改角色并完成缺少的字段。 应该考虑验证。

创建一个类Indiviual(名称,eyecolor)并创建所有者,玩家和成员的接口。 您将拥有独特的个人,并继续为他们添加功能。 因此,您将拥有所需的表,最后一列将列出不同的实现。

使用接口要比实现多继承好得多,而java就是这样做的。 所以,你最好使用它

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM