Optaplanner 护士排班:为什么需要使用 SkillProficiency Class 而不是将技能变量嵌入到员工内部 Class?
Optaplanner Nurse Rostering : Why Need To Use SkillProficiency Class Rather Than Embedded The skill variable Inside The Employee Class?
在 OptaPlanner Nurse Rostering 示例中,有 SkillProficiency class:
public class SkillProficiency extends AbstractPersistable {
private Employee employee;
private Skill skill;
public Employee getEmployee() {
return employee;
}
public void setEmployee(Employee employee) {
this.employee = employee;
}
public Skill getSkill() {
return skill;
}
public void setSkill(Skill skill) {
this.skill = skill;
}
@Override
public String toString() {
return employee + "-" + skill;
}
}
这是员工 class:
public class Employee extends AbstractPersistable {
private String code;
private String name;
private Contract contract;
private Map<ShiftDate, DayOffRequest> dayOffRequestMap;
private Map<ShiftDate, DayOnRequest> dayOnRequestMap;
private Map<Shift, ShiftOffRequest> shiftOffRequestMap;
private Map<Shift, ShiftOnRequest> shiftOnRequestMap;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Contract getContract() {
return contract;
}
public void setContract(Contract contract) {
this.contract = contract;
}
public int getWeekendLength() {
return getContract().getWeekendLength();
}
public Map<ShiftDate, DayOffRequest> getDayOffRequestMap() {
return dayOffRequestMap;
}
public void setDayOffRequestMap(Map<ShiftDate, DayOffRequest> dayOffRequestMap) {
this.dayOffRequestMap = dayOffRequestMap;
}
public Map<ShiftDate, DayOnRequest> getDayOnRequestMap() {
return dayOnRequestMap;
}
public void setDayOnRequestMap(Map<ShiftDate, DayOnRequest> dayOnRequestMap) {
this.dayOnRequestMap = dayOnRequestMap;
}
public Map<Shift, ShiftOffRequest> getShiftOffRequestMap() {
return shiftOffRequestMap;
}
public void setShiftOffRequestMap(Map<Shift, ShiftOffRequest> shiftOffRequestMap) {
this.shiftOffRequestMap = shiftOffRequestMap;
}
public Map<Shift, ShiftOnRequest> getShiftOnRequestMap() {
return shiftOnRequestMap;
}
public void setShiftOnRequestMap(Map<Shift, ShiftOnRequest> shiftOnRequestMap) {
this.shiftOnRequestMap = shiftOnRequestMap;
}
public String getLabel() {
return "Employee " + name;
}
@Override
public String toString() {
return code + "(" + name + ")";
}
}
还有技能class:
public class Skill extends AbstractPersistable {
private String code;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
@Override
public String toString() {
return code;
}
}
我想知道为什么它选择使用 SkillProficiency class 而不是将技能变量嵌入到 Employee class 中?如果我们嵌入它会更简单吗?
这个决定背后一定有充分的理由,但我就是想不通。如果有人知道,请与我分享。
而且,如果我将 skill 变量嵌入到 Employee class 中也可以吗?这样做会有什么不好的影响?
谢谢和问候。
这确实是 class 图表设计的选择。甚至可能是品味问题。
Employee 到 Skill 是多对多关系(另请参阅 grudolf 的评论)。在这种情况下,我更喜欢将 ManyToMany 关系也设计为 class。这有几个优点:
- 与 table 在关系数据库中的外观非常相似(这使得与 JPA 的集成可能更容易)
- 可扩展性:如果在未来的某个时候,我们想对员工的技能进行评分,我们可以只添加一个字段
int rating
到SkillProficiency
。
- 通常更容易断言模型一致性。
您可以轻松地扩展此模型以在 class Employee
上添加 List<SkillProficiency> proficiencyList
(就此而言 class Skill
上的 and/or ).我没有这样做的唯一原因是因为我还不需要它。
替代设计(我不喜欢)是让 class Employee
有一个 List<Skill>
和 class Skill
有一个 List<Employee>
。 OptaPlanner 中没有任何内容阻止您使用该模型:我们不想将设计决定强加于您。但我确实担心使用该模型编写高效的 scoreDRL 可能会更难......
在 OptaPlanner Nurse Rostering 示例中,有 SkillProficiency class:
public class SkillProficiency extends AbstractPersistable {
private Employee employee;
private Skill skill;
public Employee getEmployee() {
return employee;
}
public void setEmployee(Employee employee) {
this.employee = employee;
}
public Skill getSkill() {
return skill;
}
public void setSkill(Skill skill) {
this.skill = skill;
}
@Override
public String toString() {
return employee + "-" + skill;
}
}
这是员工 class:
public class Employee extends AbstractPersistable {
private String code;
private String name;
private Contract contract;
private Map<ShiftDate, DayOffRequest> dayOffRequestMap;
private Map<ShiftDate, DayOnRequest> dayOnRequestMap;
private Map<Shift, ShiftOffRequest> shiftOffRequestMap;
private Map<Shift, ShiftOnRequest> shiftOnRequestMap;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Contract getContract() {
return contract;
}
public void setContract(Contract contract) {
this.contract = contract;
}
public int getWeekendLength() {
return getContract().getWeekendLength();
}
public Map<ShiftDate, DayOffRequest> getDayOffRequestMap() {
return dayOffRequestMap;
}
public void setDayOffRequestMap(Map<ShiftDate, DayOffRequest> dayOffRequestMap) {
this.dayOffRequestMap = dayOffRequestMap;
}
public Map<ShiftDate, DayOnRequest> getDayOnRequestMap() {
return dayOnRequestMap;
}
public void setDayOnRequestMap(Map<ShiftDate, DayOnRequest> dayOnRequestMap) {
this.dayOnRequestMap = dayOnRequestMap;
}
public Map<Shift, ShiftOffRequest> getShiftOffRequestMap() {
return shiftOffRequestMap;
}
public void setShiftOffRequestMap(Map<Shift, ShiftOffRequest> shiftOffRequestMap) {
this.shiftOffRequestMap = shiftOffRequestMap;
}
public Map<Shift, ShiftOnRequest> getShiftOnRequestMap() {
return shiftOnRequestMap;
}
public void setShiftOnRequestMap(Map<Shift, ShiftOnRequest> shiftOnRequestMap) {
this.shiftOnRequestMap = shiftOnRequestMap;
}
public String getLabel() {
return "Employee " + name;
}
@Override
public String toString() {
return code + "(" + name + ")";
}
}
还有技能class:
public class Skill extends AbstractPersistable {
private String code;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
@Override
public String toString() {
return code;
}
}
我想知道为什么它选择使用 SkillProficiency class 而不是将技能变量嵌入到 Employee class 中?如果我们嵌入它会更简单吗? 这个决定背后一定有充分的理由,但我就是想不通。如果有人知道,请与我分享。 而且,如果我将 skill 变量嵌入到 Employee class 中也可以吗?这样做会有什么不好的影响? 谢谢和问候。
这确实是 class 图表设计的选择。甚至可能是品味问题。
Employee 到 Skill 是多对多关系(另请参阅 grudolf 的评论)。在这种情况下,我更喜欢将 ManyToMany 关系也设计为 class。这有几个优点:
- 与 table 在关系数据库中的外观非常相似(这使得与 JPA 的集成可能更容易)
- 可扩展性:如果在未来的某个时候,我们想对员工的技能进行评分,我们可以只添加一个字段
int rating
到SkillProficiency
。 - 通常更容易断言模型一致性。
您可以轻松地扩展此模型以在 class Employee
上添加 List<SkillProficiency> proficiencyList
(就此而言 class Skill
上的 and/or ).我没有这样做的唯一原因是因为我还不需要它。
替代设计(我不喜欢)是让 class Employee
有一个 List<Skill>
和 class Skill
有一个 List<Employee>
。 OptaPlanner 中没有任何内容阻止您使用该模型:我们不想将设计决定强加于您。但我确实担心使用该模型编写高效的 scoreDRL 可能会更难......