java - 多态性和树结构

标签 java database hibernate oop polymorphism

在提出以下问题之前:rest api and polymorphism

我想知道也许我的整个数据库模式和类结构是错误的。 当前的结构是:

  • 人员基础抽象类包含姓名和年龄
  • CHILD EXTENDS PERSON 包含最喜欢的电视节目
  • PARENT EXTENDS PERSON 包含 child 列表
  • GRANDPARENT EXTENDS PERSON 包含 parent 列表

在数据库中,每个子类型的表都组织在表中

我想到也许要重构这些类,因为子类型不会添加任何有值(value)的字段,除了子项/父项列表之外,只有一个类包含所有 字段:

 @Entity
 class Person{
  @ManyToOne 
  private Person parent;   //parent==null is a grandparent

  @OneToMany
  private List<Person> children;
}

但是,这样做的问题是,在我的业务逻辑中,父子和祖 parent 确实有不同的行为,这样就很难区分 此外,子女 parent 不能是祖 parent 。

另一个问题是,假设我保留当前的类结构
分离类并没有真正帮助我,因为我正在使用服务层
我无法知道我需要哪个服务类别,例如:

class PeopleController extends Controller { 
    public Result savePerson() {
      Person p = objectMapper.readValue.. // deseralizes to correct subtype
      // saving logic is different for each subtype, hence I need to 
      // find correct repository for this subtype but I don't want to use 
      // instance of or switch case, but to use polymorphism, but can't think 

一种没有实现我不想要的 Activity 记录的方法 } }

最佳答案

类型的确定可以完全根据状态确定,并且不需要使用多态性,因为您的问题首先没有提供任何使用它的真正基础。您定义为收集的属性对于所有 Person 来说似乎都是合理的。

  1. 是包含非空子集的任何人。
  2. 所有 Person 实例均构成一个Child,但对于本练习,它可能意味着包含子集的任何人。
  3. GrandParent 是任何作为Parent 的人,但也要求子集中至少有一个实例是Parent >.

考虑到这一点,我们可以考虑按如下方式重构数据模型。

@Entity
public class Person {
  @Id
  @GeneratedValue
  private Integer id;
  private String name;
  private Integer age;
  // any person can have this, not just children imo :)
  private String favoriteShow;

  @OneToMany(mappedBy = "parent")
  private Set<Person> children;

  @ManyToOne
  private Person parent;

  @Transient
  public boolean isChild() {
    return children == null || children.isEmpty();
  }

  @Transient
  public boolean isParent() {
    return !isChild();
  }

  @Transient
  public boolean isGrandParent() {
    return isParent() 
         && children.stream().filter( Person::isParent ).count() > 0;
  }
}

即使使用这种方法,您的逻辑也可以基于 boolean transient 方法检查进行分支。当然,您可以通过多种方式来优化这些方法,但我不会太担心,因为这些检查已经在 J​​DK8 上得到了很好的优化。

这里的好处是,您可以简单地拥有一个与 Controller 交互的 Person 服务,并且很可能有一个 Person 存储库,因为数据是作为一种类型对齐的。

我意识到每种类型的保存逻辑都不同,但我的问题是它真的必须不同吗?也许更深入地推理为什么需要拆分这些可以帮助我们提供更多背景信息。

关于java - 多态性和树结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38802725/

相关文章:

Java - 如果文本文件存在,则创建 append "1"的新文件

数据库推荐

php - mysql_query如何显示if条件的html

SQL Server Management Studio 查询检查数据是否损坏(选择、连接等)

java - 将 "new map"结果绑定(bind)到 Hibernate 中的对象

java - iPad/iPhone 上的 HTTP 字节范围协议(protocol)客户端行为

java - 使用 modifyHandshake 在 WebSocket 握手中添加 header

java - HikariCP 忽略连接超时,不从从数据库读取

spring - hibernate logback sql

sql - Hibernate:更新为来自其他表的总和