之后询问以下问题:rest api and polymorphism
我想知道我的整个数据库架构和类结构可能是错误的。 目前的结构是:
在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
没有实现我不想要的活动记录的方式 } }
答案 0 :(得分:1)
type 的确定可以根据状态完全确定,并且不需要使用多态,因为您的问题没有提供任何真正的基础在第一名。您定义为收集的属性对于所有Person
来说似乎都是合理的。
Parent
是包含非空子集的任何人。Person
个实例构成Child
,但对于此练习,它可能暗示任何包含空子集的人。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;
}
}
即使采用这种方法,您的逻辑也可以基于布尔瞬态方法检查进行分支。当然有一些方法可以优化这些方法,但我不会太担心,因为这些检查已经在JDK8上得到了很好的优化。
这里的好处是,您只需拥有一个与您的控制器交互的Person
服务,并且很可能是Person
存储库,因为数据是作为一种类型对齐的。
我意识到你的保存逻辑每种类型都不同,但我的问题是它真的必须有所不同吗?也许更深入的推理为什么这些需要分裂可以帮助我们提供更多的背景。