Java类设计选型:教授层级用继承还是枚举及业务规则落地
方案选型与实现建议
一、方案选型结论:优先选枚举方案,放弃继承
- 你的场景中三类教授仅存在规则限制差异,没有需要重写的本质行为差异,继承会导致类爆炸,后续新增职称需要新增子类,维护成本高
- 枚举+单一Professor类的方案更灵活,规则可集中管理,符合开闭原则
二、具体实现优化
1. 基础枚举定义
首先补全教授职称枚举、假期类型枚举:
// 教授职称枚举 public enum ProfessorRank { FULL_PROFESSOR, ASSOCIATE_PROFESSOR, ASSISTANT_PROFESSOR } // 假期类型枚举 public enum LeaveType { PAID, UNPAID }
2. 假期独立封装
建议将假期封装为独立的LeaveRecord类,符合单一职责原则,方便后续扩展审批状态、请假时间段等属性:
public class LeaveRecord { private LeaveType type; private int days; // 可扩展字段:申请日期、审批状态、事由等 public LeaveRecord(LeaveType type, int days) { this.type = type; this.days = days; } // getter方法省略 }
3. Professor核心类实现
所有公共属性、业务规则都集中在Professor类中,差异化规则通过职称判断实现:
public class Professor { private ProfessorRank rank; private Department department; private List<LeaveRecord> leaveRecords = new ArrayList<>(); // 仅助理教授需要赋值的授课量字段 private Integer courseCount; // 构造器初始化时校验助理教授的最低授课量要求 public Professor(ProfessorRank rank, Department department, Integer courseCount) { this.rank = rank; this.department = department; if (rank == ProfessorRank.ASSISTANT_PROFESSOR) { if (courseCount == null || courseCount < 10) { throw new IllegalArgumentException("助理教授需满足最低10门授课量要求"); } this.courseCount = courseCount; } } // 假期申请方法,统一处理所有校验规则 public void applyLeave(LeaveRecord leave) { // 校验助理教授无薪假期总时长限制 if (leave.getType() == LeaveType.UNPAID && rank == ProfessorRank.ASSISTANT_PROFESSOR) { // 统计已申请的无薪假期总天数 int usedUnpaidDays = leaveRecords.stream() .filter(record -> LeaveType.UNPAID.equals(record.getType())) .mapToInt(LeaveRecord::getDays) .sum(); if (usedUnpaidDays + leave.getDays() > 90) { throw new IllegalArgumentException("助理教授无薪假期总时长不得超过3个月"); } } // 校验通过后添加假期记录 leaveRecords.add(leave); } // 其他业务方法、getter省略 }
三、原实现问题修正
你原有代码将无薪假期校验放在构造器中是不合理的:构造器是初始化教授对象的阶段,此时还未产生假期申请动作,校验没有实际意义,规则校验应该绑定到「申请假期」的业务动作上。
内容的提问来源于stack exchange,提问作者rohit
相关产品推荐
相关产品推荐

