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

17 KiB
Raw Blame History

设计原则

**本文引用的文件** - [GFramework.Core/architecture/Architecture.cs](file://GFramework.Core/architecture/Architecture.cs) - [GFramework.Core/system/AbstractSystem.cs](file://GFramework.Core/system/AbstractSystem.cs) - [GFramework.Core/command/AbstractCommand.cs](file://GFramework.Core/command/AbstractCommand.cs) - [GFramework.Core/query/AbstractQuery.cs](file://GFramework.Core/query/AbstractQuery.cs) - [GFramework.Core/model/AbstractModel.cs](file://GFramework.Core/model/AbstractModel.cs) - [GFramework.Core/property/BindableProperty.cs](file://GFramework.Core/property/BindableProperty.cs) - [GFramework.Core/events/EasyEvent.cs](file://GFramework.Core/events/EasyEvent.cs) - [GFramework.Core/ioc/IocContainer.cs](file://GFramework.Core/ioc/IocContainer.cs) - [GFramework.Core/state/StateMachine.cs](file://GFramework.Core/state/StateMachine.cs) - [GFramework.Core.Abstractions/controller/IController.cs](file://GFramework.Core.Abstractions/controller/IController.cs) - [GFramework.Core.Abstractions/system/ISystem.cs](file://GFramework.Core.Abstractions/system/ISystem.cs) - [GFramework.Core.Abstractions/model/IModel.cs](file://GFramework.Core.Abstractions/model/IModel.cs) - [GFramework.Core.Abstractions/command/ICommand.cs](file://GFramework.Core.Abstractions/command/ICommand.cs) - [GFramework.Core.Abstractions/query/IQuery.cs](file://GFramework.Core.Abstractions/query/IQuery.cs) - [GFramework.Core/README.md](file://GFramework.Core/README.md)

目录

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

简介

本文件面向GFramework的设计原则最佳实践围绕单一职责原则SRP、开闭原则OCP、里氏替换原则LSP、接口隔离原则ISP与依赖倒置原则DIP展开结合框架中的架构、系统、命令、查询、模型、事件、属性绑定与IoC容器等模块给出在游戏开发中的落地方法与反例警示。文档同时提供PlayerController与CombatSystem等典型组件的实践路径帮助读者在GFramework中正确实现这些设计原则。

项目结构

GFramework采用“分层+横切关注点”的架构组织方式:

  • 分层Model数据、System业务逻辑、Controller控制、Utility工具
  • 横切Command/Query/Event贯穿各层形成清晰的读写分离与事件驱动通信
  • 生命周期Architecture集中管理组件注册、初始化、销毁与阶段转换
graph TB
subgraph "架构层"
A["Architecture<br/>集中管理生命周期与阶段"]
IOC["IocContainer<br/>依赖注入容器"]
end
subgraph "数据层"
M["AbstractModel<br/>数据模型基类"]
end
subgraph "业务层"
S["AbstractSystem<br/>系统基类"]
CQ["AbstractCommand / AbstractQuery<br/>命令/查询基类"]
end
subgraph "控制层"
CTRL["IController<br/>控制器契约"]
end
subgraph "工具层"
U["Utility<br/>无状态工具"]
end
subgraph "通信"
EVT["EasyEvent<br/>简单事件"]
BP["BindableProperty<br/>可绑定属性"]
end
A --> IOC
A --> M
A --> S
A --> U
CTRL --> CQ
S --> EVT
M --> BP
CTRL --> BP

图表来源

章节来源

核心组件

  • Architecture集中管理组件注册、生命周期与阶段转换体现统一调度与阶段式管理
  • AbstractSystem系统基类提供初始化/销毁与架构阶段事件处理
  • AbstractModel模型基类实现初始化与架构阶段事件处理
  • AbstractCommand/AbstractQuery命令/查询基类,提供执行入口与上下文感知
  • IocContainer线程安全的IoC容器支持注册、获取、冻结与批量接口注册
  • BindableProperty可绑定属性提供值变更事件与比较器定制
  • EasyEvent简单事件系统支持注册/注销与触发
  • StateMachine状态机支持状态注册、切换、历史记录与拒绝回调

章节来源

架构总览

下图展示了命令执行、事件传播与数据绑定在GFramework中的典型流程体现横切关注点与分层协作

sequenceDiagram
participant UI as "UI/Controller"
participant CMD as "AbstractCommand"
participant SYS as "AbstractSystem"
participant MOD as "AbstractModel"
participant EVT as "EasyEvent"
participant BP as "BindableProperty"
UI->>CMD : "SendCommand()"
CMD->>SYS : "执行业务逻辑"
SYS->>MOD : "读取/修改模型数据"
MOD->>BP : "属性变更触发事件"
BP-->>UI : "回调更新UI"
SYS->>EVT : "发送事件"
EVT-->>SYS : "通知订阅者"
EVT-->>UI : "更新UI/触发逻辑"

图表来源

详细组件分析

单一职责原则SRP

  • 核心理念:一个类只负责一项职责,变更理由唯一
  • 在GFramework中的体现
    • AbstractModel仅负责数据与状态不包含业务逻辑
    • AbstractSystem仅负责业务逻辑与事件处理不直接操作UI
    • AbstractCommand/AbstractQuery分别封装写操作与读操作职责清晰
    • Architecture集中管理生命周期与阶段不承担业务逻辑
    • IocContainer专注对象注册与获取不参与业务
  • 违反SRP的常见问题
    • Model中混入业务逻辑导致难以测试与复用
    • System中夹杂UI更新逻辑导致耦合度高
    • Command中包含多个不相关职责导致难以维护

章节来源

开闭原则OCP

  • 核心理念:对扩展开放,对修改关闭
  • 在GFramework中的体现
    • 通过事件系统扩展新功能无需修改既有System
    • 新增System只需订阅现有事件插入自身逻辑
    • 通过接口组合而非继承扩展能力
  • 违反OCP的常见问题
    • 在既有System中硬编码新分支逻辑
    • 直接修改已有事件结构导致兼容性问题
    • 通过继承扩展而非接口组合导致类爆炸

章节来源

里氏替换原则LSP

  • 核心理念:子类可以替换父类而不影响程序正确性
  • 在GFramework中的体现
    • AbstractSystem/AbstractModel等抽象基类提供稳定的虚方法与生命周期钩子
    • 子类仅覆盖必要方法如OnInit/OnExecute不影响外部调用契约
    • 通过接口如ISystem、IModel保证可替换性
  • 违反LSP的常见问题
    • 子类覆盖方法改变了外部预期的行为(如破坏初始化顺序)
    • 子类抛出父类未声明的异常导致调用方崩溃

章节来源

接口隔离原则ISP

  • 核心理念:客户端不应依赖不需要的接口
  • 在GFramework中的体现
    • 小而专注的接口组合如ICanGetModel、ICanSendCommand、ICanRegisterEvent
    • IController通过组合上述能力接口避免“胖接口”
    • Command/Query/Event均以最小接口暴露所需能力
  • 违反ISP的常见问题
    • 一个接口承载过多职责导致实现类负担过重
    • 为满足某功能而被迫实现不相关的接口

章节来源

依赖倒置原则DIP

  • 核心理念:高层模块不应依赖低层模块,二者都应依赖抽象;抽象不应依赖细节;细节应依赖抽象
  • 在GFramework中的体现
    • 所有组件通过接口交互ISystem、IModel、ICommand等
    • 通过IocContainer注入依赖降低耦合
    • Architecture作为高层调度器依赖抽象而非具体实现
  • 违反DIP的常见问题
    • 直接new底层实现导致高层模块紧耦合
    • 通过具体类型强耦合,难以替换实现或编写测试

章节来源

依赖分析

GFramework通过Architecture集中管理组件生命周期IocContainer提供依赖注入事件与属性绑定实现松耦合通信。

graph LR
ARCH["Architecture"] --> IOC["IocContainer"]
ARCH --> MOD["AbstractModel"]
ARCH --> SYS["AbstractSystem"]
ARCH --> UT["Utility"]
SYS --> EVT["EasyEvent"]
MOD --> BP["BindableProperty"]
CTRL["IController"] --> CMD["AbstractCommand"]
CTRL --> QRY["AbstractQuery"]

图表来源

章节来源

性能考虑

  • 组件初始化顺序与阶段Architecture按Utility/Model/System三阶段有序初始化减少跨层依赖引发的初始化失败
  • 线程安全与冻结IocContainer在初始化完成后冻结避免并发注册导致的竞态
  • 事件与属性绑定:事件与属性变更均采用轻量回调,注意避免在高频帧中频繁注册/注销
  • 状态机历史:限制最大历史长度,避免内存膨胀

章节来源

故障排查指南

  • 初始化失败Architecture在初始化异常时进入FailedInitialization阶段并发送事件检查Init()中注册顺序与依赖
  • 注销遗漏:事件与属性绑定需及时注销,避免内存泄漏与逻辑错误
  • 阶段转换非法:严格阶段验证(可配置)下,非法转换会抛出异常,检查阶段转换合法性
  • 容器冻结冻结后禁止注册确保在Ready前完成所有注册

章节来源

结论

GFramework通过清晰的分层、接口隔离与依赖倒置有效支撑了SRP、OCP、LSP、ISP与DIP五大设计原则。在实际游戏中建议

  • 将业务逻辑放入System数据放入Model控制与UI分离
  • 通过事件与命令/查询扩展功能,避免修改既有实现
  • 使用接口组合而非继承扩展能力
  • 通过Architecture与IocContainer集中管理生命周期与依赖

附录

典型组件实践PlayerController

  • 职责协调UI与业务监听模型变化并更新界面
  • 实践要点:
    • 通过依赖注入获取IArchitecture避免直接new
    • 使用BindableProperty.RegisterWithInitValue进行数据绑定
    • 使用UnRegisterList统一管理注销避免内存泄漏

章节来源

典型组件实践CombatSystem

  • 职责:处理战斗相关业务逻辑,响应攻击事件并更新玩家状态
  • 实践要点:
    • 通过事件驱动响应AttackEvent等避免紧耦合
    • 使用GetModel()读取数据避免直接访问UI
    • 通过SendEvent通知其他组件如UI更新

章节来源

设计原则应用流程图(命令执行)

flowchart TD
Start(["开始"]) --> BuildCmd["构建命令"]
BuildCmd --> Exec["执行命令"]
Exec --> ReadModel["读取模型数据"]
ReadModel --> Mutate["修改模型数据"]
Mutate --> FireEvt["发送事件"]
FireEvt --> Notify["通知订阅者"]
Notify --> UpdateUI["更新UI"]
UpdateUI --> End(["结束"])

图表来源