Java 处理模型中条件字段的最佳方法
我有3个模型,分别代表足球俱乐部里的人,比如说,人,角色和职位Java 处理模型中条件字段的最佳方法,java,model,architecture,Java,Model,Architecture,我有3个模型,分别代表足球俱乐部里的人,比如说,人,角色和职位 public class Person { private Long id; private String name; private Role role; } public class Role { private Long id; private String name; //like manager, goalkeeping_coach, player } public class
public class Person {
private Long id;
private String name;
private Role role;
}
public class Role {
private Long id;
private String name; //like manager, goalkeeping_coach, player
}
public class Position {
private Long id;
private String name; //striker, midfielder, defender, goalkeeper
}
问题是位置
只对角色为玩家的人有意义。所以如果我这样做了
public class Person {
private Long id;
private String name;
private Role role;
private Position position;
}
然后,对于所有不具有player
角色的person
实例,position
字段将存储空值。类似地,可能还有其他属性仅适用于manager
和/或goalkeeping\u coach
实例
我试着把人
类抽象化
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Person {
private Long id;
private String name;
private Role role;
}
public class Player extends Person {
private Position position;
}
public class Manager extends Person {
}
这将导致播放器
和管理器
实例保存在不同的表中。但是如果人的角色
发生变化(比如一名球员退休成为俱乐部经理),问题就会出现。然后我必须将行从一个表移动到另一个表(比如删除player
实例,并使用相同的数据(不包括位置
数据)创建一个新的manager
实例),这似乎不是一个好办法
那么,处理这种情况的最佳方法是什么?在第一种情况下可以使用空值吗?解决这个问题的一种方法是让同一个表同时为person和manager以及其他任何类型的person提供服务。
根据人员类型,您可能会有未使用的行,但所有公共字段都将保留在该表中。这样,当角色更改时,就不需要删除行并在另一个表上创建它们。
您必须为人员类型添加一个字段 这里的第一个基本区别是我们讨论的是java端代码还是数据库端代码
对于Java表示:
从人身上衍生出球员和经理似乎是正确的。那里没有空字段。该行为将考虑它是一个玩家还是一个管理者,您可以编写使玩家成为管理者的转移构造函数(或者反之亦然,如果有意义的话)
对于数据库表示:
可以使用空字段(它们在空间上很便宜,您可以通过空检查进行查询)。是否要将它们映射到自己的表中取决于是单独查询它们,还是合并查询它们。有时,您希望查询人员
,而不是仅查询球员
,例如,以估计总工资。然后您必须union
(假设您使用某种形式的SQL数据库)
因此,基本上正确的答案是,根据您的整个体系结构和软件的用途,没有一个正确的答案,但您必须在关键位置进行调整,当涉及到数据库交互时。要求可以更改人员
和角色
之间的连接。
该模型可以反映,如果您为此连接以及Person
和Position
// Person table has only Person details
public class Person {
private Long id;
private String name;
}
// Role table has only Role details
public class Role {
private Long id;
private String name; //like manager, goalkeeping_coach, player
}
// Position table has only ...
public class Position {
private Long id;
private String name; //striker, midfielder, defender, goalkeeper
}
// connection of Person and Role
public class PersonRole {
private Long person_id;
private Long role_id;
}
// connection of Person and Position
public class PersonPosition {
private Long person_id;
private Long position_id;
}
该设计既解决了人员角色转换的要求,又解决了职位条件相关性的要求。它还满足了未来的需求,比如一个人有多个角色和职位
编辑:
我想我描述的实际上是数据库模型。在Java中,您可以对多对多关系(如果使用某种ORM)的连接表进行建模。您遇到了一个常见问题。尽管经理符合“是个人”标准,但这可能只适用于特定的时间段,而数据库记录通常适用于更长的时间段
对此建模的正确方法是使用Person和Role表(您已经有了),再加上PersonRole链接表,该表将包含personId、roleId、startDate和endDate字段。这将解决数据建模问题,但会使代码复杂化
然而,许多应用程序只关注瞬间(例如,下一个游戏日期、下一个发薪日)。这些可以使用您建议的“管理者扩展人”继承权,因为它在某个时间实例中是正确的。您可以为玩家创建一个类,为管理者创建一个类,而不是使用name
字段。