GeWuYou 4c5e3e01a3 docs(core): 更新文档说明架构与平台无关性及新特性
- 更新 Architecture 包文档,强调与 Godot 解耦设计
- 修改 IArchitecture 接口方法参数命名规范
- 添加架构阶段感知接口 IArchitecturePhaseAware 说明
- 补充架构模块接口 IArchitectureModule 和异步初始化接口说明
- 更新架构初始化流程描述,增加模块安装系统介绍
- 修订使用示例,展示依赖注入而非单例访问模式
- 更新 Logging 包文档结构,重新组织核心接口和类说明
- 添加日志工厂提供程序和解析器使用说明
- 修正 Property 包文档中的比较器使用说明
- 更新主 README 强调平台无关性和模块化设计
- 修订架构图和数据流向说明,体现阶段式生命周期管理
- [skip ci]
2026-01-10 12:45:12 +08:00

508 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 │ 控制层:处理用户输入
├─────────────────────────────────────────┤
│ System │ 逻辑层:业务逻辑
├─────────────────────────────────────────┤
│ Model │ 数据层:游戏状态
├─────────────────────────────────────────┤
│ Utility │ 工具层:无状态工具
└─────────────────────────────────────────┘
```
### 横切关注点
```
Command ──┐
Query ──┼──→ 跨层操作(修改/查询数据)
Event ──┘
```
### 架构阶段
```
初始化Init → BeforeUtilityInit → AfterUtilityInit → BeforeModelInit → AfterModelInit → BeforeSystemInit → AfterSystemInit → Ready
销毁Destroy → Destroying → Destroyed
```
## 架构图
### 整体架构
```
┌──────────────────┐
│ 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<int> Health { get; } = new(100);
public BindableProperty<int> 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<EnemyAttackEvent>(OnEnemyAttack);
}
private void OnEnemyAttack(EnemyAttackEvent e)
{
var playerModel = this.GetModel<PlayerModel>();
// 处理业务逻辑:计算伤害、更新数据
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<PlayerModel>();
// 数据绑定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** | 架构核心,管理所有组件生命周期 | [查看](architecture/README.md) |
| **constants** | 框架常量定义 | 本文档 |
| **model** | 数据模型层,存储状态 | [查看](model/README.md) |
| **system** | 业务逻辑层,处理业务规则 | [查看](system/README.md) |
| **controller** | 控制器层,连接视图和逻辑 | (在 Abstractions 中) |
| **utility** | 工具类层,提供无状态工具 | [查看](utility/README.md) |
| **command** | 命令模式,封装写操作 | [查看](command/README.md) |
| **query** | 查询模式,封装读操作 | [查看](query/README.md) |
| **events** | 事件系统,组件间通信 | [查看](events/README.md) |
| **property** | 可绑定属性,响应式编程 | [查看](property/README.md) |
| **ioc** | IoC 容器,依赖注入 | [查看](ioc/README.md) |
| **rule** | 规则接口,定义组件约束 | [查看](rule/README.md) |
| **extensions** | 扩展方法,简化 API 调用 | [查看](extensions/README.md) |
| **logging** | 日志系统,记录运行日志 | [查看](logging/README.md) |
| **environment** | 环境接口,提供运行环境信息 | [查看](environment/README.md) |
## 组件联动
### 1. 初始化流程
```
创建 Architecture 实例
└─> Init()
├─> RegisterModel → Model.SetContext() → Model.Init()
├─> RegisterSystem → System.SetContext() → System.Init()
└─> RegisterUtility → Utility 注册到容器
```
### 2. Command 执行流程
```
Controller.SendCommand(command)
└─> command.Execute()
└─> command.OnDo() // 子类实现
├─> GetModel<T>() // 获取数据
├─> 修改 Model 数据
└─> SendEvent() // 发送事件
```
### 3. Event 传播流程
```
组件.SendEvent(event)
└─> TypeEventSystem.Send(event)
└─> 通知所有订阅者
├─> Controller 响应 → 更新 UI
├─> System 响应 → 执行逻辑
└─> Model 响应 → 更新状态
```
### 4. BindableProperty 数据绑定
```
Model: BindableProperty<int> Health = new(100);
Controller: Health.RegisterWithInitValue(hp => UpdateUI(hp))
修改值: Health.Value = 50 → 触发所有回调 → 更新 UI
```
## 最佳实践
### 1. 分层职责原则
每一层都有明确的职责边界,遵循这些原则能让代码更清晰、更易维护。
**Model 层**
```csharp
// 好:只存储数据
public class PlayerModel : AbstractModel
{
public BindableProperty<int> 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<AttackEvent>(OnAttack);
}
private void OnAttack(AttackEvent e)
{
var target = this.GetModel<PlayerModel>();
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<Event1>(OnEvent1)
.AddToUnregisterList(_unregisterList);
model.Property.Register(OnPropertyChanged)
.AddToUnregisterList(_unregisterList);
}
public void Cleanup()
{
_unregisterList.UnRegisterAll();
}
```
### 4. 性能优化技巧
```csharp
// 低效:每帧都查询
var model = _architecture.GetModel<PlayerModel>(); // 频繁调用
// 高效:缓存引用
private PlayerModel _playerModel;
public void Initialize()
{
_playerModel = _architecture.GetModel<PlayerModel>(); // 只查询一次
}
```
## 设计理念
框架的设计遵循 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.0.0
**许可证**: Apache 2.0