建模类:层次结构还是属性?

时间:2015-04-17 14:06:35

标签: java jpa hierarchy data-modeling

我目前有这两个实体: 标题和熟悉(家庭/亲属/亲属)。

熟悉[0 .. *]< ------> [1] Titular

这两个类具有一个人的公共属性(firstName,lastName,birthDate ....),它们是2种 Affiliate

我想统一一个超类(泛化)中的那些,但我无法弄清楚的是我应该使Titular和Familiar扩展Person或添加Person作为它们的属性。

人也必须独立存在(不能是抽象的),并非所有人都是关联公司 但!我还需要一种方法来建立/处理Titular和Familiar的公共行为。

Person [1]< ------> [0 .. *] Titular

人[1]< ------> [0 .. *]熟悉

Titular [1]< ------> [0 .. *]熟悉

所以怀疑是:

public class Titular extend Person
public class Familiar extend Person {

public class Titular implement Affiliate {
    private Person person;

public class Familiar implement Affiliate {
    private Titular t;
    private Person person;

或(第三个想法)

public class Person {
public abstract class Affiliate {
    protected Person person;
public class Titular extends Affiliate {

3 个答案:

答案 0 :(得分:1)

我看到它的方式,所有关联公司也是人(或者你有例外吗?)!所以正确的层次结构是:

Person --- Affiliate --- Titular 
                      \- Familiar

现在,关于继承或有一个指针......这就是所谓的组合v / s继承,并且两者都有很好的参数。选择组成的主要原因是

  1. 可变或可选的关系:比如说,汽车的拥有者可以改变,或者汽车没有拥有者。一只猫不能停下来成为动物而成为别的东西。
  2. 不同的公共API:虽然工作量更大,但是组合允许您手动转发要从内部指针公开的任何API,隐藏或更改“父”中的内容。
  3. 一般情况下,当ClassA IS-A ClassB发现继承更有意义时,您不希望这种情况发生变化,也不希望两个类都呈现不同的API。你会在任何地方都看到这个建议,它似乎像手套一样适合你的例子。

答案 1 :(得分:0)

详细说明,我们需要以下行为(如果我理解正确的话):

Titular是支持Person功能的Affiliate

FamiliarPerson,他支持Affiliate的功能,并与Titular相关联。

在阅读了这两行足够多次之后,一个看似合理的可能解决方案是:

public class Titular extends Person implements Affiliate {

public class Familiar extends Person implements Affiliate {
    private Titular t;

答案 2 :(得分:0)

经过几次测试后,我决定继承组合。 由于其中一个标签是" JPA",此解决方案必须进行映射/注释

..并且没有任何可能的注释适合

@Inheritance(strategy = InheritanceType.JOINED/SINGLE_TABLE/TABLE_PER_CLASS)

如果Titular和Familiar从Person扩展,则ORM需要" DTYPE"人物中的专栏,对我来说是无用的,因为没有关于一个人可以/将会在其生命中有多少名称或熟悉的事项,它必须是一个人的登记册。

成为会员是一个"概念"或行为,我需要它做一些多态的任务,它没有任何可持续的属性(现在!),我将建立它的接口。

@Entity
public class Persona {
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private Integer id;


@Entity
public class Titular implements Afiliado {
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private Integer id;
   @JoinColumn(nullable = false)
   @ManyToOne(optional = false)
   private Persona persona;

@Entity
public class Familiar implements Afiliado {
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private Integer id;
   @JoinColumn(nullable = false)
   @ManyToOne(optional = false)
   private Persona persona;
   @ManyToOne
   private Titular titular;

public interface Afiliado {
   public String getNumero();
   //trick but necessary
   public Persona getPersona();

   //another default Java 8 implementations..
}