抽象类通过字段、构造器、模板方法和抽象契约构建可信赖的模型骨架,统一状态与生命周期管理,固化业务流程,暴露清晰行为契约,并支持安全扩展。

抽象类规范领域模型的公共行为,核心是把模型中“所有子类都该有、都该做、且做法高度一致”的部分收上来,把“每个子类必须自己决定怎么做的部分”明确留成钩子。它不是写个空壳等子类填空,而是用字段、构造器、模板方法和抽象契约共同建立可信赖的模型骨架。
统一状态与生命周期管理
领域模型通常共享关键字段(如id、createdAt、status、version)和初始化逻辑。这些不该在每个实体里重复声明和赋值。
- 在抽象基类中定义 protected 字段,例如
protected String id;、protected LocalDateTime createdAt = LocalDateTime.now();、protected Integer version = 1; - 提供 protected 构造函数,如
protected BaseEntity(String id),子类通过super(id)显式调用,确保 id 不为空、不可变 - 封装通用校验,比如
validateId()或ensureNotDeleted(),在关键操作前自动触发,避免子类遗漏
固化业务流程骨架
领域操作常有稳定顺序:校验 → 执行核心逻辑 → 更新状态 → 发布事件。这部分流程不能由子类随意打乱。
- 定义 public final 方法 作为主入口,例如
public final void submitOrder() { validate(); doSubmit(); updateStatus(); emitEvent(); } - 将真正差异化的环节设为 protected abstract,如
protected abstract void doSubmit();和protected abstract DomainEvent emitEvent(); - 把可复用但允许微调的步骤设为 protected 默认实现,比如
protected void updateStatus() { this.status = "SUBMITTED"; },子类可选择性重写
暴露清晰的行为契约
抽象方法名不是技术占位符,而是对领域语义的直接表达。模糊命名会导致子类内部加 if 分支,破坏多态性。
立即学习“Java免费学习笔记(深入)”;
- 避免
public abstract void handle(Request req);这类泛化签名——子类还得根据req.getType()分支,说明职责没切准 - 改用具体领域动词+名词组合,例如
public abstract Money calculateDiscount(Order order);、public abstract List<violation> validateEligibility(Customer customer);</violation> - 配合 Javadoc 明确前置条件(pre-condition)和后置约束(post-condition),让子类实现时有据可依
支持安全的扩展与增强
领域模型常需按场景叠加能力(如审计、缓存、权限检查),抽象类可提供结构化支持,而非靠子类各自硬编码。
- 定义 protected 钩子方法,如
protected void beforeSave() {}、protected void afterLoad() {},默认空实现,子类按需重写 - 引入 策略字段,如
protected final AuditPolicy auditPolicy;,由子类在构造时注入,基类统一调用其logChange() - 所有涉及状态变更的操作,优先走基类封装的模板路径,避免子类绕过校验或日志直接修改字段


















