在Java中将子对象用作父对象属性是不好的做法吗?

时间:2018-10-26 08:17:24

标签: java

例如,我有一个称为实体的类,看起来像

public class Entity {
   private User userCreated;
   private Date dateCreated;
   private User userModified;
   private Date dateModified;
}

然后我有一个User类,它实际上是Entity的子类

public class User extends Entity {
    private String username;
}

我觉得关系中存在一个循环,但是对象在我的系统中是以这种方式关联的,因为我的所有数据都是一个Entity,我的所有实体都是由User(包括User)创建的,所以我用户是实体。

我已经测试了代码并且可以正常工作,我的问题是,这种设计不好吗?如果不好,有没有更好的方法来实现呢?

4 个答案:

答案 0 :(得分:3)

一般来说,这没什么不好的。如果基类包含要求其所有子类都有知识的逻辑(例如,为了确定在某个方法调用中返回哪个实例),这只是一个不好的做法,因为这可能会破坏基类(或强制其进行处理)随时更新)。

另一方面,JDK本身包含引用其子类的类的示例。

例如(尽管可能有点作弊),Basic类包含对ObjectString的引用,这是其子类。

如果您的班级关系需要它,那没有什么错。

答案 1 :(得分:1)

在我看来,这没有什么坏处。

这实际上只是问题“对象可以包含自身吗?”的略微修改版本。在两种情况下答案都是相同的-是的,没关系。

例如,链表中的一个节点将包含对下一个和上一个节点的引用,例如:

class Node
{
    private Node next;
    private Node previous;
}

这个设计也没有什么坏事。

在您的情况下,User Entity,只是更加专业。上面示例的类比可能是NodeBranchedNode


不过,您可能要考虑的一件事是,如果某个用户要求某个用户创建了它们,那么哪个用户将创建第一个用户?有点鸡和蛋的情况。也许第一个用户的userCreateduserModified等于null?也许他们会指向自己?

答案 2 :(得分:1)

通常,您不需要双向依赖性,也不想基类知道其子类,而只希望反向子类,因为它们全都可能在类之间建立强大的耦合,即任何子类之间的更改可能对双方都有影响。
但这并不意味着您永远都不想使用这种耦合。
有时这种耦合是不合需要的,但有时却是合乎需要的,在这里它似乎是合乎需要的耦合:父级和子级在语义上非常紧密地耦合在一起,因此以后很少有人想要将用户或实体隔离为他们之间更加独立。
因此,您接受甚至希望这种耦合避免没有价值的重复/复杂性。

请注意,您可以通过引入定义实体的接口来使事物脱钩,但是要获得一件伟大的事情,有很多代码:

public interface EntityAble {
   User getUserCreated();
   Date getDateCreated();
   User getUuserModified();
   Date getDateModified();
  // setters
}

定义实体,例如:

public class Entity implements EntityAble {
   private User userCreated;
   private Date dateCreated;
   private User userModified;
   private Date dateModified;
   // override getters/setters
}

,用户为:

public class User implements EntityAble {
   private String username;      
   private User userCreated;
   private Date dateCreated;
   private User userModified;
   private Date dateModified;
   // override getters/setters  
}

现在,实体由用户字段组成,而用户字段不是实体,而是很多重复/ LOC,不一定能获得某些收益。
在某些用例中,这种设计可能很有意义,但是对于您的实际需求来说,这是一项开销。

答案 3 :(得分:0)

仅当业务领域中存在抽象时,才需要添加抽象。提出以下问题-是用户实体还是仅仅是用户名(只是字符串)?不要忘记YAGNI原理。