From 51492b1dcd73c0ff65676f0aaca25f7f7890687f Mon Sep 17 00:00:00 2001 From: gewuyou <95328647+GeWuYou@users.noreply.github.com> Date: Sat, 21 Mar 2026 15:53:09 +0800 Subject: [PATCH] fix(docs): remove dead ADR references --- docs/zh-CN/core/architecture.md | 1 - docs/zh-CN/core/index.md | 1313 +++++++++++++++---------------- 2 files changed, 656 insertions(+), 658 deletions(-) diff --git a/docs/zh-CN/core/architecture.md b/docs/zh-CN/core/architecture.md index 6ae229b..90b5c34 100644 --- a/docs/zh-CN/core/architecture.md +++ b/docs/zh-CN/core/architecture.md @@ -228,4 +228,3 @@ architecture.RegisterLifecycleHook(new MyLifecycleHook()); **相关文档**: - [核心框架概述](./index.md) -- [ADR-001: 拆分 Architecture 核心类](/docs/adr/001-split-architecture-class.md) diff --git a/docs/zh-CN/core/index.md b/docs/zh-CN/core/index.md index fb9602b..4e8618b 100644 --- a/docs/zh-CN/core/index.md +++ b/docs/zh-CN/core/index.md @@ -1,657 +1,656 @@ -# GFramework.Core 核心框架 - -> 一个基于 CQRS、MVC 和事件驱动的轻量级游戏开发架构框架 - -## 目录 - -- [框架概述](#框架概述) -- [核心概念](#核心概念) -- [架构图](#架构图) -- [快速开始](#快速开始) -- [包说明](#包说明) -- [组件联动](#组件联动) -- [最佳实践](#最佳实践) -- [设计理念](#设计理念) - -## 框架概述 - -本框架是一个与平台无关的轻量级架构,它结合了多种经典设计模式: - -- **MVC 架构模式** - 清晰的层次划分 -- **CQRS 模式** - 命令查询职责分离 -- **IoC/DI** - 依赖注入和控制反转 -- **事件驱动** - 松耦合的组件通信 -- **响应式编程** - 可绑定属性和数据流 -- **阶段式生命周期管理** - 精细化的架构状态控制 - -**重要说明**:GFramework.Core 是与平台无关的核心模块,不包含任何 Godot 特定代码。Godot 集成功能在 GFramework.Godot 包中实现。 - -### 核心特性 - -- **清晰的分层架构** - Model、View、Controller、System、Utility 各司其职 -- **类型安全** - 基于泛型的组件获取和事件系统 -- **松耦合** - 通过事件和接口实现组件解耦 -- **易于测试** - 依赖注入和纯函数设计 -- **可扩展** - 基于接口的规则体系 -- **生命周期管理** - 自动的注册和注销机制 -- **模块化** - 支持架构模块安装 -- **平台无关** - Core 模块可以在任何 .NET 环境中使用 - -## 核心概念 - -### 五层架构 - -``` -┌─────────────────────────────────────────┐ -│ View / UI │ UI 层:用户界面 -├─────────────────────────────────────────┤ -│ Controller │ 控制层:连接 UI 和业务逻辑 -├─────────────────────────────────────────┤ -│ System │ 逻辑层:业务逻辑 -├─────────────────────────────────────────┤ -│ Model │ 数据层:游戏状态 -├─────────────────────────────────────────┤ -│ Utility │ 工具层:无状态工具 -└─────────────────────────────────────────┘ -``` - -### 横切关注点 - -``` -Command ──┐ -Query ──┼──→ 跨层操作(修改/查询数据) -Event ──┘ -``` - -### 架构阶段 - -框架提供了精细化的生命周期管理,包含 11 个阶段: - -``` -初始化流程: -None → BeforeUtilityInit → AfterUtilityInit → BeforeModelInit → AfterModelInit → BeforeSystemInit → AfterSystemInit → Ready - -销毁流程: -Ready → Destroying → Destroyed - -异常流程: -Any → FailedInitialization -``` - -每个阶段都会触发 `PhaseChanged` 事件,允许组件监听架构状态变化。 - -## 架构图 - -### 整体架构 - -从 v1.1.0 开始,Architecture 类采用模块化设计,将职责分离到专门的管理器中: - -``` - ┌──────────────────┐ - │ Architecture │ ← 核心协调器 - └────────┬─────────┘ - │ - ┌────────────────────┼────────────────────┐ - │ │ │ - ┌────▼────────┐ ┌──────▼──────┐ ┌────────▼────────┐ - │ Lifecycle │ │ Component │ │ Modules │ - │ Manager │ │ Registry │ │ Manager │ - └─────────────┘ └─────────────┘ └─────────────────┘ - │ │ │ - │ │ │ - 生命周期管理 组件注册管理 模块管理 - - 阶段转换 - System 注册 - 模块安装 - - 钩子管理 - Model 注册 - 行为注册 - - 初始化/销毁 - Utility 注册 -``` - -这种设计遵循单一职责原则,使代码更易维护和测试。详见 [ADR-001](/docs/adr/001-split-architecture-class.md)。 - -``` - ┌──────────────────┐ - │ Architecture │ ← 管理所有组件 - └────────┬─────────┘ - │ - ┌────────────────────┼────────────────────┐ - │ │ │ - ┌───▼────┐ ┌───▼────┐ ┌───▼─────┐ - │ Model │ │ System │ │ Utility │ - │ 层 │ │ 层 │ │ 层 │ - └───┬────┘ └───┬────┘ └────────┘ - │ │ - │ ┌─────────────┤ - │ │ │ - ┌───▼────▼───┐ ┌───▼──────┐ - │ Controller │ │ Command/ │ - │ 层 │ │ Query │ - └─────┬──────┘ └──────────┘ - │ - ┌─────▼─────┐ - │ View │ - │ UI │ - └───────────┘ -``` - -### 数据流向 - -``` -用户输入 → Controller → Command → System → Model → Event → Controller → View 更新 - -查询流程:Controller → Query → Model → 返回数据 -``` - -## 快速开始 - -本框架采用"约定优于配置"的设计理念,只需 4 步即可搭建完整的架构。 - -### 为什么需要这个框架? - -在传统开发中,我们经常遇到这些问题: - -- 代码耦合严重:UI 直接访问游戏逻辑,逻辑直接操作 UI -- 难以维护:修改一个功能需要改动多个文件 -- 难以测试:业务逻辑和 UI 混在一起无法独立测试 -- 难以复用:代码紧密耦合,无法在其他项目中复用 - -本框架通过清晰的分层解决这些问题。 - -### 1. 定义架构(Architecture) - -**作用**:Architecture 是整个应用的"中央调度器",负责管理所有组件的生命周期。 - -```csharp -using GFramework.Core.Architecture; - -public class GameArchitecture : Architecture -{ - protected override void Init() - { - // 注册 Model - 游戏数据 - RegisterModel(new PlayerModel()); - - // 注册 System - 业务逻辑 - RegisterSystem(new CombatSystem()); - - // 注册 Utility - 工具类 - RegisterUtility(new StorageUtility()); - } -} -``` - -**优势**: - -- **依赖注入**:组件通过上下文获取架构引用 -- **集中管理**:所有组件注册在一处,一目了然 -- **生命周期管理**:自动初始化和销毁 -- **平台无关**:可以在任何 .NET 环境中使用 - -### 2. 定义 Model(数据层) - -**作用**:Model 是应用的"数据库",只负责存储和管理状态。 - -```csharp -public class PlayerModel : AbstractModel -{ - // 使用 BindableProperty 实现响应式数据 - public BindableProperty Health { get; } = new(100); - public BindableProperty Gold { get; } = new(0); - - protected override void OnInit() - { - // Model 中可以监听自己的数据变化 - Health.Register(hp => - { - if (hp <= 0) this.SendEvent(new PlayerDiedEvent()); - }); - } -} - -// 也可以不使用 BindableProperty -public class PlayerModel : AbstractModel -{ - public int Health { get; private set; } - public int Gold { get; private set; } - - protected override void OnInit() - { - Health = 100; - Gold = 0; - } -} -``` - -**优势**: - -- **数据响应式**:BindableProperty 让数据变化自动通知监听者 -- **职责单一**:只存储数据,不包含复杂业务逻辑 -- **易于测试**:可以独立测试数据逻辑 - -### 3. 定义 System(业务逻辑层) - -**作用**:System 是应用的"大脑",处理所有业务逻辑。 - -```csharp -public class CombatSystem : AbstractSystem -{ - protected override void OnInit() - { - // System 通过事件驱动,响应游戏中的各种事件 - this.RegisterEvent(OnEnemyAttack); - } - - private void OnEnemyAttack(EnemyAttackEvent e) - { - var playerModel = this.GetModel(); - - // 处理业务逻辑:计算伤害、更新数据 - playerModel.Health.Value -= e.Damage; - - // 发送事件通知其他组件 - this.SendEvent(new PlayerTookDamageEvent { Damage = e.Damage }); - } -} -``` - -**优势**: - -- **事件驱动**:通过事件解耦,不同 System 之间松耦合 -- **可组合**:多个 System 协同工作,每个专注自己的领域 -- **易于扩展**:新增功能只需添加新的 System 和事件监听 - -### 4. 定义 Controller(控制层) - -**作用**:Controller 是"桥梁",连接 UI 和业务逻辑。 - -```csharp -public class PlayerController : IController -{ - // 通过依赖注入获取架构 - private readonly IArchitecture _architecture; - - public PlayerController(IArchitecture architecture) - { - _architecture = architecture; - } - - // 监听模型变化 - public void Initialize() - { - var playerModel = _architecture.GetModel(); - - // 数据绑定:Model 数据变化自动更新 UI - playerModel.Health.RegisterWithInitValue(OnHealthChanged); - } - - private void OnHealthChanged(int hp) - { - // 更新 UI 显示 - UpdateHealthDisplay(hp); - } - - private void UpdateHealthDisplay(int hp) { /* UI 更新逻辑 */ } -} -``` - -**优势**: - -- **自动更新 UI**:通过 BindableProperty,数据变化自动反映到界面 -- **分离关注点**:UI 逻辑和业务逻辑完全分离 -- **易于测试**:可以通过依赖注入模拟架构进行测试 - -### 完成!现在你有了一个完整的架构 - -这 4 步完成后,你就拥有了: - -- **清晰的数据层**(Model) -- **独立的业务逻辑**(System) -- **灵活的控制层**(Controller) -- **统一的生命周期管理**(Architecture) - -### 下一步该做什么? - -1. **添加 Command**:封装用户操作(如购买物品、使用技能) -2. **添加 Query**:封装数据查询(如查询背包物品数量) -3. **添加更多 System**:如任务系统、背包系统、商店系统 -4. **使用 Utility**:添加工具类(如存档工具、数学工具) -5. **使用模块**:通过 IArchitectureModule 扩展架构功能 - -## 包说明 - -### Architecture 内部结构 (v1.1.0+) - -从 v1.1.0 开始,Architecture 类采用模块化设计,将原本 708 行的单一类拆分为 4 个职责清晰的类: - -#### 1. Architecture (核心协调器) - -**职责**: 提供统一的公共 API,协调各个管理器 - -**主要方法**: - -- `RegisterSystem()` - 注册系统 -- `RegisterModel()` - 注册模型 -- `RegisterUtility()` - 注册工具 -- `InstallModule()` - 安装模块 -- `InitializeAsync()` / `Initialize()` - 初始化架构 -- `DestroyAsync()` / `Destroy()` - 销毁架构 - -**事件**: - -- `PhaseChanged` - 阶段变更事件 - -#### 2. ArchitectureLifecycle (生命周期管理器) - -**职责**: 管理架构的生命周期和阶段转换 - -**核心功能**: - -- 11 个架构阶段的管理和转换 -- 生命周期钩子 (IArchitectureLifecycleHook) 管理 -- 组件初始化 (按 Utility → Model → System 顺序) -- 组件销毁 (逆序销毁) -- 就绪状态管理 - -**关键方法**: - -- `EnterPhase()` - 进入指定阶段 -- `RegisterLifecycleHook()` - 注册生命周期钩子 -- `InitializeAllComponentsAsync()` - 初始化所有组件 -- `DestroyAsync()` - 异步销毁 - -#### 3. ArchitectureComponentRegistry (组件注册管理器) - -**职责**: 管理 System、Model、Utility 的注册 - -**核心功能**: - -- 组件注册和验证 -- 自动设置组件上下文 (IContextAware) -- 自动注册组件生命周期 (IInitializable、IDestroyable) -- 支持实例注册和类型注册 - -**关键方法**: - -- `RegisterSystem()` - 注册系统 -- `RegisterModel()` - 注册模型 -- `RegisterUtility()` - 注册工具 - -#### 4. ArchitectureModules (模块管理器) - -**职责**: 管理架构模块和中介行为 - -**核心功能**: - -- 模块安装 (IArchitectureModule) -- 中介行为注册 (Mediator Behaviors) - -**关键方法**: - -- `InstallModule()` - 安装模块 -- `RegisterMediatorBehavior()` - 注册中介行为 - -#### 设计优势 - -这种模块化设计带来以下优势: - -1. **单一职责**: 每个类只负责一个明确的功能 -2. **易于测试**: 可以独立测试每个管理器 -3. **易于维护**: 修改某个功能不影响其他功能 -4. **易于扩展**: 添加新功能更容易 -5. **代码安全**: 消除了 `null!` 断言,所有字段在构造后立即可用 - -详细的设计决策请参考 [ADR-001: 拆分 Architecture 核心类](/docs/adr/001-split-architecture-class.md)。 - ---- - -## 包说明 - -| 包名 | 职责 | 文档 | -|------------------|-----------------|----------------------| -| **architecture** | 架构核心,管理所有组件生命周期 | [查看](./architecture) | -| **constants** | 框架常量定义 | 本文档 | -| **model** | 数据模型层,存储状态 | [查看](./model) | -| **system** | 业务逻辑层,处理业务规则 | [查看](./system) | -| **controller** | 控制器层,连接视图和逻辑 | (在 Abstractions 中) | -| **utility** | 工具类层,提供无状态工具 | [查看](./utility) | -| **command** | 命令模式,封装写操作 | [查看](./command) | -| **query** | 查询模式,封装读操作 | [查看](./query) | -| **events** | 事件系统,组件间通信 | [查看](./events) | -| **property** | 可绑定属性,响应式编程 | [查看](./property) | -| **ioc** | IoC 容器,依赖注入 | [查看](./ioc) | -| **rule** | 规则接口,定义组件约束 | [查看](./rule) | -| **extensions** | 扩展方法,简化 API 调用 | [查看](./extensions) | -| **logging** | 日志系统,记录运行日志 | [查看](./logging) | -| **environment** | 环境接口,提供运行环境信息 | [查看](./environment) | -| **localization** | 本地化系统,多语言支持 | [查看](./localization) | - -## 组件联动 - -### 1. 初始化流程 - -``` -创建 Architecture 实例 - └─> 构造函数 - ├─> 初始化 Logger - ├─> 创建 ArchitectureLifecycle - ├─> 创建 ArchitectureComponentRegistry - └─> 创建 ArchitectureModules - └─> InitializeAsync() - ├─> OnInitialize() (用户注册组件) - │ ├─> RegisterModel → Model.SetContext() - │ ├─> RegisterSystem → System.SetContext() - │ └─> RegisterUtility → 注册到容器 - └─> InitializeAllComponentsAsync() - ├─> BeforeUtilityInit → Utility.Initialize() - ├─> BeforeModelInit → Model.Initialize() - ├─> BeforeSystemInit → System.Initialize() - └─> Ready -``` - -**重要变更 (v1.1.0)**: 管理器现在在构造函数中初始化,而不是在 InitializeAsync 中。这消除了 `null!` 断言,提高了代码安全性。 - -### 2. Command 执行流程 - -``` -Controller.SendCommand(command) - └─> command.Execute() - └─> command.OnDo() // 子类实现 - ├─> GetModel() // 获取数据 - ├─> 修改 Model 数据 - └─> SendEvent() // 发送事件 -``` - -### 3. Event 传播流程 - -``` -组件.SendEvent(event) - └─> TypeEventSystem.Send(event) - └─> 通知所有订阅者 - ├─> Controller 响应 → 更新 UI - ├─> System 响应 → 执行逻辑 - └─> Model 响应 → 更新状态 -``` - -### 4. BindableProperty 数据绑定 - -``` -Model: BindableProperty Health = new(100); -Controller: Health.RegisterWithInitValue(hp => UpdateUI(hp)) -修改值: Health.Value = 50 → 触发所有回调 → 更新 UI -``` - -## 最佳实践 - -### 1. 分层职责原则 - -每一层都有明确的职责边界,遵循这些原则能让代码更清晰、更易维护。 - -**Model 层**: - -```csharp -// 好:只存储数据 -public class PlayerModel : AbstractModel -{ - public BindableProperty Health { get; } = new(100); - protected override void OnInit() { } -} - -// 坏:包含业务逻辑 -public class PlayerModel : AbstractModel -{ - public void TakeDamage(int damage) // 业务逻辑应在 System - { - Health.Value -= damage; - if (Health.Value <= 0) Die(); - } -} -``` - -**System 层**: - -```csharp -// 好:处理业务逻辑 -public class CombatSystem : AbstractSystem -{ - protected override void OnInit() - { - this.RegisterEvent(OnAttack); - } - - private void OnAttack(AttackEvent e) - { - var target = this.GetModel(); - int finalDamage = CalculateDamage(e.BaseDamage, target); - target.Health.Value -= finalDamage; - } -} -``` - -### 2. 通信方式选择指南 - -| 通信方式 | 使用场景 | 优势 | -|----------------------|-----------|----------| -| **Command** | 用户操作、修改状态 | 可撤销、可记录 | -| **Query** | 查询数据、检查条件 | 明确只读意图 | -| **Event** | 通知其他组件 | 松耦合、可扩展 | -| **BindableProperty** | 数据变化通知 | 自动化、不会遗漏 | - -### 3. 生命周期管理 - -**为什么需要注销?** - -忘记注销监听器会导致: - -- **内存泄漏**:对象无法被 GC 回收 -- **逻辑错误**:已销毁的对象仍在响应事件 - -```csharp -// 使用 UnRegisterList 统一管理 -private IUnRegisterList _unregisterList = new UnRegisterList(); - -public void Initialize() -{ - this.RegisterEvent(OnEvent1) - .AddToUnregisterList(_unregisterList); - - model.Property.Register(OnPropertyChanged) - .AddToUnregisterList(_unregisterList); -} - -public void Cleanup() -{ - _unregisterList.UnRegisterAll(); -} -``` - -### 4. 性能优化技巧 - -```csharp -// 低效:每帧都查询 -var model = _architecture.GetModel(); // 频繁调用 - -// 高效:缓存引用 -private PlayerModel _playerModel; - -public void Initialize() -{ - _playerModel = _architecture.GetModel(); // 只查询一次 -} -``` - -## 设计理念 - -框架的设计遵循 SOLID 原则和经典设计模式。 - -### 1. 单一职责原则(SRP) - -- **Model**:只负责存储数据 -- **System**:只负责处理业务逻辑 -- **Controller**:只负责协调和输入处理 -- **Utility**:只负责提供工具方法 - -### 2. 开闭原则(OCP) - -- 通过**事件系统**添加新功能,无需修改现有代码 -- 新的 System 可以监听现有事件,插入自己的逻辑 - -### 3. 依赖倒置原则(DIP) - -- 所有组件通过接口交互 -- 通过 IoC 容器注入依赖 -- 易于替换实现和编写测试 - -### 4. 接口隔离原则(ISP) - -```csharp -// 小而专注的接口 -public interface ICanGetModel : IBelongToArchitecture { } -public interface ICanSendCommand : IBelongToArchitecture { } -public interface ICanRegisterEvent : IBelongToArchitecture { } - -// 组合需要的能力 -public interface IController : - ICanGetModel, - ICanSendCommand, - ICanRegisterEvent { } -``` - -### 5. 组合优于继承 - -通过接口组合获得能力,而不是通过继承。 - -### 框架核心设计模式 - -| 设计模式 | 应用位置 | 解决的问题 | 带来的好处 | -|-----------|------------|----------|--------| -| **工厂模式** | IoC 容器 | 组件的创建和管理 | 解耦创建逻辑 | -| **观察者模式** | Event 系统 | 组件间的通信 | 松耦合通信 | -| **命令模式** | Command | 封装操作请求 | 支持撤销重做 | -| **策略模式** | System | 不同的业务逻辑 | 易于切换策略 | -| **依赖注入** | 整体架构 | 组件间的依赖 | 自动管理依赖 | -| **模板方法** | Abstract 类 | 定义算法骨架 | 统一流程规范 | - -### 平台无关性 - -- **GFramework.Core**:纯 .NET 库,无任何平台特定代码 -- **GFramework.Godot**:Godot 特定实现,包含 Node 扩展、GodotLogger 等 -- 可以轻松将 Core 框架移植到其他平台(Unity、.NET MAUI 等) - ---- - -**版本**: 1.1.0 -**更新日期**: 2026-03-17 -**许可证**: Apache 2.0 - -## 更新日志 - -### v1.1.0 (2026-03-17) - -**重大重构**: - -- 拆分 Architecture 类为 4 个职责清晰的类 -- 消除 3 处 `null!` 强制断言,提高代码安全性 -- 在构造函数中初始化管理器,符合"构造即完整"原则 -- 添加 `PhaseChanged` 事件,支持阶段监听 - -**向后兼容**: 所有公共 API 保持不变,现有代码无需修改。 - -详见 [ADR-001: 拆分 Architecture 核心类](/docs/adr/001-split-architecture-class.md) \ No newline at end of file +# GFramework.Core 核心框架 + +> 一个基于 CQRS、MVC 和事件驱动的轻量级游戏开发架构框架 + +## 目录 + +- [框架概述](#框架概述) +- [核心概念](#核心概念) +- [架构图](#架构图) +- [快速开始](#快速开始) +- [包说明](#包说明) +- [组件联动](#组件联动) +- [最佳实践](#最佳实践) +- [设计理念](#设计理念) + +## 框架概述 + +本框架是一个与平台无关的轻量级架构,它结合了多种经典设计模式: + +- **MVC 架构模式** - 清晰的层次划分 +- **CQRS 模式** - 命令查询职责分离 +- **IoC/DI** - 依赖注入和控制反转 +- **事件驱动** - 松耦合的组件通信 +- **响应式编程** - 可绑定属性和数据流 +- **阶段式生命周期管理** - 精细化的架构状态控制 + +**重要说明**:GFramework.Core 是与平台无关的核心模块,不包含任何 Godot 特定代码。Godot 集成功能在 GFramework.Godot 包中实现。 + +### 核心特性 + +- **清晰的分层架构** - Model、View、Controller、System、Utility 各司其职 +- **类型安全** - 基于泛型的组件获取和事件系统 +- **松耦合** - 通过事件和接口实现组件解耦 +- **易于测试** - 依赖注入和纯函数设计 +- **可扩展** - 基于接口的规则体系 +- **生命周期管理** - 自动的注册和注销机制 +- **模块化** - 支持架构模块安装 +- **平台无关** - Core 模块可以在任何 .NET 环境中使用 + +## 核心概念 + +### 五层架构 + +``` +┌─────────────────────────────────────────┐ +│ View / UI │ UI 层:用户界面 +├─────────────────────────────────────────┤ +│ Controller │ 控制层:连接 UI 和业务逻辑 +├─────────────────────────────────────────┤ +│ System │ 逻辑层:业务逻辑 +├─────────────────────────────────────────┤ +│ Model │ 数据层:游戏状态 +├─────────────────────────────────────────┤ +│ Utility │ 工具层:无状态工具 +└─────────────────────────────────────────┘ +``` + +### 横切关注点 + +``` +Command ──┐ +Query ──┼──→ 跨层操作(修改/查询数据) +Event ──┘ +``` + +### 架构阶段 + +框架提供了精细化的生命周期管理,包含 11 个阶段: + +``` +初始化流程: +None → BeforeUtilityInit → AfterUtilityInit → BeforeModelInit → AfterModelInit → BeforeSystemInit → AfterSystemInit → Ready + +销毁流程: +Ready → Destroying → Destroyed + +异常流程: +Any → FailedInitialization +``` + +每个阶段都会触发 `PhaseChanged` 事件,允许组件监听架构状态变化。 + +## 架构图 + +### 整体架构 + +从 v1.1.0 开始,Architecture 类采用模块化设计,将职责分离到专门的管理器中: + +``` + ┌──────────────────┐ + │ Architecture │ ← 核心协调器 + └────────┬─────────┘ + │ + ┌────────────────────┼────────────────────┐ + │ │ │ + ┌────▼────────┐ ┌──────▼──────┐ ┌────────▼────────┐ + │ Lifecycle │ │ Component │ │ Modules │ + │ Manager │ │ Registry │ │ Manager │ + └─────────────┘ └─────────────┘ └─────────────────┘ + │ │ │ + │ │ │ + 生命周期管理 组件注册管理 模块管理 + - 阶段转换 - System 注册 - 模块安装 + - 钩子管理 - Model 注册 - 行为注册 + - 初始化/销毁 - Utility 注册 +``` + +这种设计遵循单一职责原则,使代码更易维护和测试。 + +``` + ┌──────────────────┐ + │ Architecture │ ← 管理所有组件 + └────────┬─────────┘ + │ + ┌────────────────────┼────────────────────┐ + │ │ │ + ┌───▼────┐ ┌───▼────┐ ┌───▼─────┐ + │ Model │ │ System │ │ Utility │ + │ 层 │ │ 层 │ │ 层 │ + └───┬────┘ └───┬────┘ └────────┘ + │ │ + │ ┌─────────────┤ + │ │ │ + ┌───▼────▼───┐ ┌───▼──────┐ + │ Controller │ │ Command/ │ + │ 层 │ │ Query │ + └─────┬──────┘ └──────────┘ + │ + ┌─────▼─────┐ + │ View │ + │ UI │ + └───────────┘ +``` + +### 数据流向 + +``` +用户输入 → Controller → Command → System → Model → Event → Controller → View 更新 + +查询流程:Controller → Query → Model → 返回数据 +``` + +## 快速开始 + +本框架采用"约定优于配置"的设计理念,只需 4 步即可搭建完整的架构。 + +### 为什么需要这个框架? + +在传统开发中,我们经常遇到这些问题: + +- 代码耦合严重:UI 直接访问游戏逻辑,逻辑直接操作 UI +- 难以维护:修改一个功能需要改动多个文件 +- 难以测试:业务逻辑和 UI 混在一起无法独立测试 +- 难以复用:代码紧密耦合,无法在其他项目中复用 + +本框架通过清晰的分层解决这些问题。 + +### 1. 定义架构(Architecture) + +**作用**:Architecture 是整个应用的"中央调度器",负责管理所有组件的生命周期。 + +```csharp +using GFramework.Core.Architecture; + +public class GameArchitecture : Architecture +{ + protected override void Init() + { + // 注册 Model - 游戏数据 + RegisterModel(new PlayerModel()); + + // 注册 System - 业务逻辑 + RegisterSystem(new CombatSystem()); + + // 注册 Utility - 工具类 + RegisterUtility(new StorageUtility()); + } +} +``` + +**优势**: + +- **依赖注入**:组件通过上下文获取架构引用 +- **集中管理**:所有组件注册在一处,一目了然 +- **生命周期管理**:自动初始化和销毁 +- **平台无关**:可以在任何 .NET 环境中使用 + +### 2. 定义 Model(数据层) + +**作用**:Model 是应用的"数据库",只负责存储和管理状态。 + +```csharp +public class PlayerModel : AbstractModel +{ + // 使用 BindableProperty 实现响应式数据 + public BindableProperty Health { get; } = new(100); + public BindableProperty Gold { get; } = new(0); + + protected override void OnInit() + { + // Model 中可以监听自己的数据变化 + Health.Register(hp => + { + if (hp <= 0) this.SendEvent(new PlayerDiedEvent()); + }); + } +} + +// 也可以不使用 BindableProperty +public class PlayerModel : AbstractModel +{ + public int Health { get; private set; } + public int Gold { get; private set; } + + protected override void OnInit() + { + Health = 100; + Gold = 0; + } +} +``` + +**优势**: + +- **数据响应式**:BindableProperty 让数据变化自动通知监听者 +- **职责单一**:只存储数据,不包含复杂业务逻辑 +- **易于测试**:可以独立测试数据逻辑 + +### 3. 定义 System(业务逻辑层) + +**作用**:System 是应用的"大脑",处理所有业务逻辑。 + +```csharp +public class CombatSystem : AbstractSystem +{ + protected override void OnInit() + { + // System 通过事件驱动,响应游戏中的各种事件 + this.RegisterEvent(OnEnemyAttack); + } + + private void OnEnemyAttack(EnemyAttackEvent e) + { + var playerModel = this.GetModel(); + + // 处理业务逻辑:计算伤害、更新数据 + playerModel.Health.Value -= e.Damage; + + // 发送事件通知其他组件 + this.SendEvent(new PlayerTookDamageEvent { Damage = e.Damage }); + } +} +``` + +**优势**: + +- **事件驱动**:通过事件解耦,不同 System 之间松耦合 +- **可组合**:多个 System 协同工作,每个专注自己的领域 +- **易于扩展**:新增功能只需添加新的 System 和事件监听 + +### 4. 定义 Controller(控制层) + +**作用**:Controller 是"桥梁",连接 UI 和业务逻辑。 + +```csharp +public class PlayerController : IController +{ + // 通过依赖注入获取架构 + private readonly IArchitecture _architecture; + + public PlayerController(IArchitecture architecture) + { + _architecture = architecture; + } + + // 监听模型变化 + public void Initialize() + { + var playerModel = _architecture.GetModel(); + + // 数据绑定:Model 数据变化自动更新 UI + playerModel.Health.RegisterWithInitValue(OnHealthChanged); + } + + private void OnHealthChanged(int hp) + { + // 更新 UI 显示 + UpdateHealthDisplay(hp); + } + + private void UpdateHealthDisplay(int hp) { /* UI 更新逻辑 */ } +} +``` + +**优势**: + +- **自动更新 UI**:通过 BindableProperty,数据变化自动反映到界面 +- **分离关注点**:UI 逻辑和业务逻辑完全分离 +- **易于测试**:可以通过依赖注入模拟架构进行测试 + +### 完成!现在你有了一个完整的架构 + +这 4 步完成后,你就拥有了: + +- **清晰的数据层**(Model) +- **独立的业务逻辑**(System) +- **灵活的控制层**(Controller) +- **统一的生命周期管理**(Architecture) + +### 下一步该做什么? + +1. **添加 Command**:封装用户操作(如购买物品、使用技能) +2. **添加 Query**:封装数据查询(如查询背包物品数量) +3. **添加更多 System**:如任务系统、背包系统、商店系统 +4. **使用 Utility**:添加工具类(如存档工具、数学工具) +5. **使用模块**:通过 IArchitectureModule 扩展架构功能 + +## 包说明 + +### Architecture 内部结构 (v1.1.0+) + +从 v1.1.0 开始,Architecture 类采用模块化设计,将原本 708 行的单一类拆分为 4 个职责清晰的类: + +#### 1. Architecture (核心协调器) + +**职责**: 提供统一的公共 API,协调各个管理器 + +**主要方法**: + +- `RegisterSystem()` - 注册系统 +- `RegisterModel()` - 注册模型 +- `RegisterUtility()` - 注册工具 +- `InstallModule()` - 安装模块 +- `InitializeAsync()` / `Initialize()` - 初始化架构 +- `DestroyAsync()` / `Destroy()` - 销毁架构 + +**事件**: + +- `PhaseChanged` - 阶段变更事件 + +#### 2. ArchitectureLifecycle (生命周期管理器) + +**职责**: 管理架构的生命周期和阶段转换 + +**核心功能**: + +- 11 个架构阶段的管理和转换 +- 生命周期钩子 (IArchitectureLifecycleHook) 管理 +- 组件初始化 (按 Utility → Model → System 顺序) +- 组件销毁 (逆序销毁) +- 就绪状态管理 + +**关键方法**: + +- `EnterPhase()` - 进入指定阶段 +- `RegisterLifecycleHook()` - 注册生命周期钩子 +- `InitializeAllComponentsAsync()` - 初始化所有组件 +- `DestroyAsync()` - 异步销毁 + +#### 3. ArchitectureComponentRegistry (组件注册管理器) + +**职责**: 管理 System、Model、Utility 的注册 + +**核心功能**: + +- 组件注册和验证 +- 自动设置组件上下文 (IContextAware) +- 自动注册组件生命周期 (IInitializable、IDestroyable) +- 支持实例注册和类型注册 + +**关键方法**: + +- `RegisterSystem()` - 注册系统 +- `RegisterModel()` - 注册模型 +- `RegisterUtility()` - 注册工具 + +#### 4. ArchitectureModules (模块管理器) + +**职责**: 管理架构模块和中介行为 + +**核心功能**: + +- 模块安装 (IArchitectureModule) +- 中介行为注册 (Mediator Behaviors) + +**关键方法**: + +- `InstallModule()` - 安装模块 +- `RegisterMediatorBehavior()` - 注册中介行为 + +#### 设计优势 + +这种模块化设计带来以下优势: + +1. **单一职责**: 每个类只负责一个明确的功能 +2. **易于测试**: 可以独立测试每个管理器 +3. **易于维护**: 修改某个功能不影响其他功能 +4. **易于扩展**: 添加新功能更容易 +5. **代码安全**: 消除了 `null!` 断言,所有字段在构造后立即可用 + +详细的设计决策已在架构实现重构中落地。 + +--- + +## 包说明 + +| 包名 | 职责 | 文档 | +|------------------|-----------------|----------------------| +| **architecture** | 架构核心,管理所有组件生命周期 | [查看](./architecture) | +| **constants** | 框架常量定义 | 本文档 | +| **model** | 数据模型层,存储状态 | [查看](./model) | +| **system** | 业务逻辑层,处理业务规则 | [查看](./system) | +| **controller** | 控制器层,连接视图和逻辑 | (在 Abstractions 中) | +| **utility** | 工具类层,提供无状态工具 | [查看](./utility) | +| **command** | 命令模式,封装写操作 | [查看](./command) | +| **query** | 查询模式,封装读操作 | [查看](./query) | +| **events** | 事件系统,组件间通信 | [查看](./events) | +| **property** | 可绑定属性,响应式编程 | [查看](./property) | +| **ioc** | IoC 容器,依赖注入 | [查看](./ioc) | +| **rule** | 规则接口,定义组件约束 | [查看](./rule) | +| **extensions** | 扩展方法,简化 API 调用 | [查看](./extensions) | +| **logging** | 日志系统,记录运行日志 | [查看](./logging) | +| **environment** | 环境接口,提供运行环境信息 | [查看](./environment) | +| **localization** | 本地化系统,多语言支持 | [查看](./localization) | + +## 组件联动 + +### 1. 初始化流程 + +``` +创建 Architecture 实例 + └─> 构造函数 + ├─> 初始化 Logger + ├─> 创建 ArchitectureLifecycle + ├─> 创建 ArchitectureComponentRegistry + └─> 创建 ArchitectureModules + └─> InitializeAsync() + ├─> OnInitialize() (用户注册组件) + │ ├─> RegisterModel → Model.SetContext() + │ ├─> RegisterSystem → System.SetContext() + │ └─> RegisterUtility → 注册到容器 + └─> InitializeAllComponentsAsync() + ├─> BeforeUtilityInit → Utility.Initialize() + ├─> BeforeModelInit → Model.Initialize() + ├─> BeforeSystemInit → System.Initialize() + └─> Ready +``` + +**重要变更 (v1.1.0)**: 管理器现在在构造函数中初始化,而不是在 InitializeAsync 中。这消除了 `null!` 断言,提高了代码安全性。 + +### 2. Command 执行流程 + +``` +Controller.SendCommand(command) + └─> command.Execute() + └─> command.OnDo() // 子类实现 + ├─> GetModel() // 获取数据 + ├─> 修改 Model 数据 + └─> SendEvent() // 发送事件 +``` + +### 3. Event 传播流程 + +``` +组件.SendEvent(event) + └─> TypeEventSystem.Send(event) + └─> 通知所有订阅者 + ├─> Controller 响应 → 更新 UI + ├─> System 响应 → 执行逻辑 + └─> Model 响应 → 更新状态 +``` + +### 4. BindableProperty 数据绑定 + +``` +Model: BindableProperty Health = new(100); +Controller: Health.RegisterWithInitValue(hp => UpdateUI(hp)) +修改值: Health.Value = 50 → 触发所有回调 → 更新 UI +``` + +## 最佳实践 + +### 1. 分层职责原则 + +每一层都有明确的职责边界,遵循这些原则能让代码更清晰、更易维护。 + +**Model 层**: + +```csharp +// 好:只存储数据 +public class PlayerModel : AbstractModel +{ + public BindableProperty Health { get; } = new(100); + protected override void OnInit() { } +} + +// 坏:包含业务逻辑 +public class PlayerModel : AbstractModel +{ + public void TakeDamage(int damage) // 业务逻辑应在 System + { + Health.Value -= damage; + if (Health.Value <= 0) Die(); + } +} +``` + +**System 层**: + +```csharp +// 好:处理业务逻辑 +public class CombatSystem : AbstractSystem +{ + protected override void OnInit() + { + this.RegisterEvent(OnAttack); + } + + private void OnAttack(AttackEvent e) + { + var target = this.GetModel(); + int finalDamage = CalculateDamage(e.BaseDamage, target); + target.Health.Value -= finalDamage; + } +} +``` + +### 2. 通信方式选择指南 + +| 通信方式 | 使用场景 | 优势 | +|----------------------|-----------|----------| +| **Command** | 用户操作、修改状态 | 可撤销、可记录 | +| **Query** | 查询数据、检查条件 | 明确只读意图 | +| **Event** | 通知其他组件 | 松耦合、可扩展 | +| **BindableProperty** | 数据变化通知 | 自动化、不会遗漏 | + +### 3. 生命周期管理 + +**为什么需要注销?** + +忘记注销监听器会导致: + +- **内存泄漏**:对象无法被 GC 回收 +- **逻辑错误**:已销毁的对象仍在响应事件 + +```csharp +// 使用 UnRegisterList 统一管理 +private IUnRegisterList _unregisterList = new UnRegisterList(); + +public void Initialize() +{ + this.RegisterEvent(OnEvent1) + .AddToUnregisterList(_unregisterList); + + model.Property.Register(OnPropertyChanged) + .AddToUnregisterList(_unregisterList); +} + +public void Cleanup() +{ + _unregisterList.UnRegisterAll(); +} +``` + +### 4. 性能优化技巧 + +```csharp +// 低效:每帧都查询 +var model = _architecture.GetModel(); // 频繁调用 + +// 高效:缓存引用 +private PlayerModel _playerModel; + +public void Initialize() +{ + _playerModel = _architecture.GetModel(); // 只查询一次 +} +``` + +## 设计理念 + +框架的设计遵循 SOLID 原则和经典设计模式。 + +### 1. 单一职责原则(SRP) + +- **Model**:只负责存储数据 +- **System**:只负责处理业务逻辑 +- **Controller**:只负责协调和输入处理 +- **Utility**:只负责提供工具方法 + +### 2. 开闭原则(OCP) + +- 通过**事件系统**添加新功能,无需修改现有代码 +- 新的 System 可以监听现有事件,插入自己的逻辑 + +### 3. 依赖倒置原则(DIP) + +- 所有组件通过接口交互 +- 通过 IoC 容器注入依赖 +- 易于替换实现和编写测试 + +### 4. 接口隔离原则(ISP) + +```csharp +// 小而专注的接口 +public interface ICanGetModel : IBelongToArchitecture { } +public interface ICanSendCommand : IBelongToArchitecture { } +public interface ICanRegisterEvent : IBelongToArchitecture { } + +// 组合需要的能力 +public interface IController : + ICanGetModel, + ICanSendCommand, + ICanRegisterEvent { } +``` + +### 5. 组合优于继承 + +通过接口组合获得能力,而不是通过继承。 + +### 框架核心设计模式 + +| 设计模式 | 应用位置 | 解决的问题 | 带来的好处 | +|-----------|------------|----------|--------| +| **工厂模式** | IoC 容器 | 组件的创建和管理 | 解耦创建逻辑 | +| **观察者模式** | Event 系统 | 组件间的通信 | 松耦合通信 | +| **命令模式** | Command | 封装操作请求 | 支持撤销重做 | +| **策略模式** | System | 不同的业务逻辑 | 易于切换策略 | +| **依赖注入** | 整体架构 | 组件间的依赖 | 自动管理依赖 | +| **模板方法** | Abstract 类 | 定义算法骨架 | 统一流程规范 | + +### 平台无关性 + +- **GFramework.Core**:纯 .NET 库,无任何平台特定代码 +- **GFramework.Godot**:Godot 特定实现,包含 Node 扩展、GodotLogger 等 +- 可以轻松将 Core 框架移植到其他平台(Unity、.NET MAUI 等) + +--- + +**版本**: 1.1.0 +**更新日期**: 2026-03-17 +**许可证**: Apache 2.0 + +## 更新日志 + +### v1.1.0 (2026-03-17) + +**重大重构**: + +- 拆分 Architecture 类为 4 个职责清晰的类 +- 消除 3 处 `null!` 强制断言,提高代码安全性 +- 在构造函数中初始化管理器,符合"构造即完整"原则 +- 添加 `PhaseChanged` 事件,支持阶段监听 + +**向后兼容**: 所有公共 API 保持不变,现有代码无需修改。 +