多态性和树结构

时间:2016-08-06 09:31:13

标签: java database hibernate oop polymorphism

之后询问以下问题:rest api and polymorphism

我想知道我的整个数据库架构和类结构可能是错误的。 目前的结构是:

  • PERSON BASE PETRACT CLASS包含姓名和年龄
  • 儿童延伸人包含最喜欢的电视节目
  • PARENT EXTENDS PERSON包含儿童列表
  • GRANDPARENT EXTENDS PERSON包含父母列表

在db中为每个子类型组织表格

我想也许可以重构这些类,因为子类不会添加任何有价值的字段,除了子目录/父母列表,只有一个类包含所有 字段:

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

  @OneToMany
  private List<Person> children;
}

然而,问题在于,在我的业务逻辑中,父母和祖父母确实有不同的行为,这种方式更难以区分 此外,父母不能是祖父母。

另一个问题是,我说我正在使用当前的班级结构 分离课程并不能帮助我,因为我使用的是服务层 而且我无法拒绝我需要的服务类,例如:

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 

没有实现我不想要的活动记录的方式          }     }

1 个答案:

答案 0 :(得分:1)

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

  1. Parent是包含非空子集的任何人。
  2. 所有Person个实例构成Child,但对于此练习,它可能暗示任何包含子集的人。
  3. GrandParentParent的任何人,但也要求子集中至少有一个实例为Parent
  4. 考虑到这一点,我们可以考虑重构数据模型如下。

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

    即使采用这种方法,您的逻辑也可以基于布尔瞬态方法检查进行分支。当然有一些方法可以优化这些方法,但我不会太担心,因为这些检查已经在JDK8上得到了很好的优化。

    这里的好处是,您只需拥有一个与您的控制器交互的Person服务,并且很可能是Person存储库,因为数据是作为一种类型对齐的。

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