状态即类型:用继承表达状态层级,每个业务状态(如Draft、Approved)建模为独立类,继承自抽象基类DocumentState,统一定义canEdit()、nextState()等接口;业务对象持状态引用而非状态字段,行为由实际类型决定,变更仅替换引用,支持正交复合与事件驱动。

直接用继承模式构建带状态机转换的业务对象,关键不是套用类继承语法,而是把“状态行为”本身当作可继承、可组合的单元。它和传统类继承不同——重点不在数据结构复用,而在状态逻辑的层次化封装与精准覆盖。
状态即类型:用继承表达状态层级
把每个核心业务状态(如 Draft、Approved、Archived)建模为一个独立类,它们共同继承自抽象基类 DocumentState。这个基类不包含具体实现,只定义统一接口:canEdit()、canDelete()、nextState() 等。
-
DraftState实现canEdit() → true,nextState() → new ApprovedState() -
ApprovedState实现canEdit() → false,nextState() → new ArchivedState() - 所有子类共享基类中预置的通用校验逻辑(如权限检查钩子),避免重复写 if-else
行为继承优于数据继承
业务对象(如 Contract)自身不保存状态码或状态字段,而是持有一个 DocumentState 类型的引用。它的“当前行为”完全由该引用的实际类型决定。
- 调用
contract.submit()时,实际执行的是currentStatus.nextState() - 状态变更只需替换引用:
contract.changeState(new ApprovedState()) - 无需 switch 或 map 查表,无运行时类型判断开销
支持复合与正交状态
当业务需要多个独立状态维度(例如:主流程状态 + 审批状态 + 归档标记),可让不同状态类继承自同一基类,再通过组合方式注入业务对象。
- 定义
ApprovalState和ArchiveState,都继承自StateBase -
Contract持有approvalState: ApprovalState和archiveState: ArchiveState两个独立引用 - 每个维度的状态转换互不影响,天然支持正交性
与事件驱动机制自然对接
每个状态类可声明其响应的领域事件(如 ContractSubmitted、ApprovalRejected),并在对应方法中触发转换。
-
DraftState.on(ContractSubmitted)→ 返回new PendingApprovalState() - 上层事件总线按当前状态类型分发事件,无需全局路由配置
- 新增状态只需新增类并注册事件响应,不修改已有代码










