例如,我有一个称为实体的类,看起来像
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)创建的,所以我用户是实体。
我已经测试了代码并且可以正常工作,我的问题是,这种设计不好吗?如果不好,有没有更好的方法来实现呢?
答案 0 :(得分:3)
一般来说,这没什么不好的。如果基类包含要求其所有子类都有知识的逻辑(例如,为了确定在某个方法调用中返回哪个实例),这只是一个不好的做法,因为这可能会破坏基类(或强制其进行处理)随时更新)。
另一方面,JDK本身包含引用其子类的类的示例。
例如(尽管可能有点作弊),Basic
类包含对Object
和String
的引用,这是其子类。
如果您的班级关系需要它,那没有什么错。
答案 1 :(得分:1)
在我看来,这没有什么坏处。
这实际上只是问题“对象可以包含自身吗?”的略微修改版本。在两种情况下答案都是相同的-是的,没关系。
例如,链表中的一个节点将包含对下一个和上一个节点的引用,例如:
class Node
{
private Node next;
private Node previous;
}
这个设计也没有什么坏事。
在您的情况下,User
是的Entity
,只是更加专业。上面示例的类比可能是Node
和BranchedNode
。
不过,您可能要考虑的一件事是,如果某个用户要求某个用户创建了它们,那么哪个用户将创建第一个用户?有点鸡和蛋的情况。也许第一个用户的userCreated
和userModified
等于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原理。