GeWuYou a79f02c987 docs(api): 添加 Core API 参考文档与事件系统接口文档
- 新增 Core API 参考文档,涵盖架构与模块、数据模型与系统、命令与查询等核心组件
- 添加事件系统接口详细文档,包括 IEvent、IEventBus、IUnRegister 等接口说明
- 提供完整的 API 使用示例路径、最佳实践与性能建议
- 包含架构图、依赖关系图与故障排查指南
- 添加测试用例参考与扩展方法说明
- [skip ci]
2026-01-21 23:45:10 +08:00

19 KiB
Raw Blame History

领域驱动设计

**本文引用的文件** - [README.md](file://GFramework.Core/README.md) - [AbstractModel.cs](file://GFramework.Core/model/AbstractModel.cs) - [IModel.cs](file://GFramework.Core.Abstractions/model/IModel.cs) - [AbstractSystem.cs](file://GFramework.Core/system/AbstractSystem.cs) - [ISystem.cs](file://GFramework.Core.Abstractions/system/ISystem.cs) - [BindableProperty.cs](file://GFramework.Core/property/BindableProperty.cs) - [AbstractCommand.cs](file://GFramework.Core/command/AbstractCommand.cs) - [AbstractQuery.cs](file://GFramework.Core/query/AbstractQuery.cs) - [EventBus.cs](file://GFramework.Core/events/EventBus.cs) - [EasyEvent.cs](file://GFramework.Core/events/EasyEvent.cs) - [Architecture.cs](file://GFramework.Core/architecture/Architecture.cs) - [ContextAwareBase.cs](file://GFramework.Core/rule/ContextAwareBase.cs) - [StateMachine.cs](file://GFramework.Core/state/StateMachine.cs) - [IState.cs](file://GFramework.Core.Abstractions/state/IState.cs) - [ContextAwareStateBase.cs](file://GFramework.Core/state/ContextAwareStateBase.cs)

目录

  1. 引言
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 详细组件分析
  6. 依赖关系分析
  7. 性能考量
  8. 故障排查指南
  9. 结论
  10. 附录

引言

本教程面向希望在GFramework中实践领域驱动设计DDD的游戏开发者。我们将围绕实体Entity、值对象Value Object、领域事件Domain Event、领域服务Domain Service等核心概念结合GFramework现有的架构层、事件系统、命令/查询模式、可绑定属性与状态机等组件,给出可落地的设计与实现思路,并提供游戏开发中的典型应用案例(玩家系统、物品系统、战斗系统)。

项目结构

GFramework采用“约定优于配置”的分层架构核心分为四层View/UI、Controller、System、Model、Utility配合跨层操作Command/Query/Event与生命周期管理形成清晰的职责边界与松耦合通信机制。

graph TB
subgraph "表现层"
UI["视图/UI"]
end
subgraph "控制层"
CTRL["控制器/Controller"]
end
subgraph "业务层"
SYS["系统/System"]
end
subgraph "数据层"
MDL["模型/Model"]
PROP["可绑定属性/Property"]
end
subgraph "工具层"
UT["工具/Utility"]
end
subgraph "跨层操作"
CMD["命令/Command"]
QRY["查询/Query"]
EVT["事件/Event"]
end
UI --> CTRL
CTRL --> CMD
CTRL --> QRY
CMD --> SYS
QRY --> MDL
SYS --> MDL
MDL --> EVT
SYS --> EVT
CTRL --> EVT
CTRL --> PROP
MDL --> PROP
SYS --> UT

图表来源

章节来源

核心组件

  • 架构与生命周期:通过架构基类集中管理组件注册、初始化阶段与销毁流程,确保组件在正确时机被创建与回收。
  • 模型Model承载领域状态提供可绑定属性以实现响应式数据更新。
  • 系统System处理业务逻辑通过事件驱动与其他组件解耦。
  • 控制器Controller桥接UI与业务监听模型变化并更新界面。
  • 命令/查询:封装写操作与读操作,保证操作意图明确且可追踪。
  • 事件系统:提供类型化事件总线,支持注册、注销与触发。
  • 状态机:管理状态注册、切换与历史,支持状态转换校验与回调。

章节来源

架构总览

下图展示了GFramework中命令执行、事件传播与数据绑定的整体流程体现DDD中“命令写入状态、事件驱动协作、查询读取状态”的核心思想。

sequenceDiagram
participant UI as "用户界面/UI"
participant CTRL as "控制器/Controller"
participant CMD as "命令/Command"
participant SYS as "系统/System"
participant MDL as "模型/Model"
participant EVT as "事件总线/EventBus"
UI->>CTRL : 用户输入
CTRL->>CMD : 构造并发送命令
CMD->>SYS : 执行命令逻辑
SYS->>MDL : 修改领域状态
SYS->>EVT : 发送领域事件
EVT-->>CTRL : 通知控制器
CTRL->>UI : 更新界面显示

图表来源

详细组件分析

实体Entity

在GFramework中实体通常以“模型”形态存在承载领域不变量与状态。模型通过可绑定属性实现响应式更新同时通过事件系统对外广播状态变化。

  • 关键点

    • 模型实现初始化接口,在初始化阶段建立监听与不变量约束。
    • 使用可绑定属性作为实体的可变状态载体,避免直接暴露字段。
    • 通过事件系统发布领域事件,通知其他组件。
  • 代码片段路径

  • 设计要点

    • 将“状态”与“行为”分离:状态由模型持有,行为由系统处理。
    • 不变量通过系统逻辑在命令执行时强制校验,模型仅保存最终状态。
    • 事件用于跨组件通知,避免紧耦合。

章节来源

值对象Value Object

值对象强调“不可变性”与“相等性基于结构”。在GFramework中可通过可绑定属性的比较器定制与事件系统实现值对象语义。

  • 关键点

    • 使用可绑定属性的比较器定制,确保相等判断符合值对象语义。
    • 值对象作为命令输入或查询条件,提升意图表达力。
    • 通过事件系统传播值对象的变化,便于系统与模型响应。
  • 代码片段路径

  • 设计要点

    • 值对象不应暴露可变状态;若需变化,应通过新实例替换。
    • 在命令/查询中以值对象作为输入参数,增强可读性与可测试性。

章节来源

领域事件Domain Event

领域事件是跨组件通信的关键手段GFramework提供类型化事件总线与简单事件类支持注册、注销与触发。

  • 关键点

    • 事件类型化,确保强类型安全与可发现性。
    • 事件总线支持注册/注销与触发,便于系统与模型响应。
    • 简单事件类提供无参事件的注册/触发能力,适配部分场景。
  • 代码片段路径

  • 设计要点

    • 领域事件应描述“发生了什么”,而非“如何处理”。
    • 事件发布应发生在状态变更之后,确保订阅者看到一致状态。

章节来源

领域服务Domain Service

领域服务封装跨实体的业务逻辑与规则。在GFramework中系统层承担领域服务职责通过事件驱动与其他组件协作。

  • 关键点

    • 系统实现业务规则,监听事件并修改模型状态。
    • 通过架构基类提供的上下文能力访问容器与服务。
    • 生命周期管理确保系统在正确阶段初始化与销毁。
  • 代码片段路径

  • 设计要点

    • 领域服务不持有状态,仅处理业务规则与流程编排。
    • 通过事件与模型解耦,避免循环依赖。

章节来源

状态机(状态驱动的领域)

状态机用于管理复杂的状态流转与转换规则适合角色状态、UI状态等场景。

  • 关键点

    • 状态注册、切换、历史记录与回退。
    • 转换前的合法性校验与拒绝回调。
    • 状态进入/退出与状态变更回调。
  • 代码片段路径

  • 设计要点

    • 状态转换规则集中在状态机内,避免分散的条件判断。
    • 历史记录支持回退,便于撤销与审计。

章节来源

命令与查询CQRS

命令/查询职责分离,命令封装写操作,查询封装读操作,二者均通过上下文感知基类接入架构。

  • 关键点

    • 命令:带输入参数,执行后可能修改模型状态并发布事件。
    • 查询:只读操作,返回结果给调用方。
    • 上下文感知:命令/查询可访问架构上下文与容器。
  • 代码片段路径

  • 设计要点

    • 命令应具备可撤销/可重试能力(可结合持久化与日志)。
    • 查询应避免副作用,确保幂等性。

章节来源

依赖关系分析

下图展示DDD相关组件在GFramework中的依赖关系与交互

classDiagram
class Architecture {
+Initialize()
+RegisterModel()
+RegisterSystem()
+RegisterUtility()
+Destroy()
}
class ContextAwareBase {
+SetContext(context)
+GetContext()
+OnContextReady()
}
class AbstractModel {
+OnInit()
+OnArchitecturePhase(phase)
}
class AbstractSystem {
+Init()
+Destroy()
+OnInit()
+OnDestroy()
}
class BindableProperty~T~ {
+Value
+Register()
+RegisterWithInitValue()
+UnRegister()
}
class AbstractCommand~TInput,TResult~ {
+Execute()
+OnExecute(input)
}
class AbstractQuery~TInput,TResult~ {
+Do()
+OnDo(input)
}
class EventBus {
+Register()
+UnRegister()
+Send()
}
class StateMachine {
+Register()
+Unregister()
+ChangeTo()
+GoBack()
+GetStateHistory()
}
class IState {
+OnEnter(from)
+OnExit(to)
+CanTransitionTo(target)
}
Architecture --> AbstractModel : "注册/初始化"
Architecture --> AbstractSystem : "注册/初始化"
ContextAwareBase <|-- AbstractModel
ContextAwareBase <|-- AbstractSystem
ContextAwareBase <|-- AbstractCommand
ContextAwareBase <|-- AbstractQuery
AbstractSystem --> EventBus : "发布事件"
AbstractModel --> BindableProperty : "持有状态"
AbstractCommand --> AbstractModel : "修改状态"
AbstractQuery --> AbstractModel : "读取状态"
StateMachine --> IState : "管理状态"

图表来源

章节来源

性能考量

  • 事件风暴与订阅管理
    • 使用统一的注销列表管理事件订阅,避免重复注册与内存泄漏。
    • 事件总线按类型索引事件,减少遍历成本。
  • 可绑定属性
    • 通过比较器避免无效回调;批量更新时可使用“无事件设置”降低触发频率。
  • 状态机历史
    • 历史记录大小受控,避免无限增长导致内存压力。
  • 生命周期
    • 架构阶段化初始化与冻结容器,减少运行期开销。

[本节为通用指导,无需列出章节来源]

故障排查指南

  • 事件未触发/未收到
    • 检查事件类型是否匹配,确认注册与注销是否成对出现。
    • 确认事件总线是否在正确阶段可用。
  • 状态无法切换
    • 检查状态转换规则与目标状态是否已注册。
    • 查看拒绝回调与历史记录是否影响回退。
  • 命令执行后状态未更新
    • 确认命令是否正确修改模型状态并发布事件。
    • 检查系统是否监听到相应事件并处理。
  • UI 不更新
    • 确认模型属性使用可绑定属性并在控制器中注册回调。
    • 检查控制器是否在初始化阶段完成注册。

章节来源

结论

通过将DDD的核心概念映射到GFramework的分层架构与现有组件模型、系统、事件、命令/查询、状态机、可绑定属性),可以构建高内聚、低耦合、可测试且可演进的游戏领域模型。建议在实际项目中:

  • 将“状态”放入模型,“行为”放入系统;
  • 使用命令/查询明确写读意图;
  • 用事件解耦跨组件协作;
  • 用值对象表达不可变语义;
  • 用状态机管理复杂状态流转。

[本节为总结,无需列出章节来源]

附录

游戏开发中的DDD应用案例

  • 玩家系统Player

  • 物品系统Item

  • 战斗系统Combat

    • 领域事件:造成伤害、承受伤害、击杀、闪避。
    • 领域服务:伤害计算、护甲减免、暴击判定、状态效果。
    • 状态机:待机、移动、攻击、受击、死亡、眩晕。
    • 代码片段路径

DDD概念与GFramework组件映射表

  • 实体Entity ↔ 模型Model + 可绑定属性BindableProperty
  • 值对象Value Object ↔ 命令/查询输入 + 比较器定制
  • 领域事件Domain Event ↔ 事件总线EventBus + 简单事件EasyEvent
  • 领域服务Domain Service ↔ 系统System
  • 命令/查询CQRS ↔ 命令AbstractCommand + 查询AbstractQuery
  • 状态机State Machine ↔ 状态机StateMachine

章节来源