You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 14:06:02