Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/345.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 处理模型中条件字段的最佳方法_Java_Model_Architecture - Fatal编程技术网

Java 处理模型中条件字段的最佳方法

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

我有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 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
字段。