Checkpoint 9

This commit is contained in:
SepComet
2026-03-16 22:19:57 +08:00
parent 2e4108aebc
commit ccbd27e87e
79 changed files with 2937 additions and 2269 deletions
+192
View File
@@ -0,0 +1,192 @@
# UI 五层架构设计规范(RawData / Controller / View / Context / UseCase)
## 1. 适用范围
- 适用目录:`Assets/GameMain/Scripts/UI/*`
- 重点对象:采用五层拆分的 UI 模块(`MenuScene`、`GameScene`、`General` 下的分层 UI)
- 本文不展开 Unity GameFramework 底层实现细节,仅约束项目内 UI 代码组织与协作方式
## 2. 架构总览
UI 模块采用“输入数据 -> 业务编排 -> 展示数据 -> 渲染表现”的分层方式,核心链路如下:
1. 外部流程(Procedure/GameState)创建并绑定 UseCase
2. 通过 `GameEntry.UIRouter` 打开指定 UI
3. Controller 从 UseCase 取 RawData,并转换为 Context
4. View 使用 Context 渲染
5. View 通过事件回传交互,Controller 处理后驱动 UseCase 更新,再刷新 View
简化关系图:
```text
Procedure/GameState
-> UIRouter
-> Controller <-> UseCase
-> Context -> View
View --(CustomEvent)--> Controller
```
## 3. 五层职责定义
### 3.1 RawData 层
职责:承载“业务原始数据”,作为 UseCase 到 Controller 的传输模型。
约束:
- 命名:`XXXFormRawData`
- 只描述数据,不包含 UI 渲染行为
- 可保留领域对象或数据表对象(例如 `DRLevelUpReward`、`WeaponBase`)
- 不依赖具体 View 组件
参考:
- `Assets/GameMain/Scripts/UI/GameScene/RawData/ShopFormRawData.cs`
- `Assets/GameMain/Scripts/UI/GameScene/RawData/LevelUpFormRawData.cs`
- `Assets/GameMain/Scripts/UI/MenuScene/RawData/SelectRoleFormRawData.cs`
### 3.2 UseCase 层
职责:封装 UI 对应业务用例,负责业务规则、状态推进、数据生成。
约束:
- 实现 `IUIUseCase`
- 命名:`XXXFormUseCase`
- 对外提供 `CreateInitialModel / TryRefresh / Select / Confirm` 等语义化方法
- 返回 RawData(或结果对象),不直接操作具体 View
参考:
- `Assets/GameMain/Scripts/UI/GameScene/UseCase/ShopFormUseCase.cs`
- `Assets/GameMain/Scripts/UI/GameScene/UseCase/LevelUpFormUseCase.cs`
- `Assets/GameMain/Scripts/UI/MenuScene/UseCase/SelectRoleFormUseCase.cs`
### 3.3 Controller 层
职责:UI 编排层,连接 UseCase 与 View,管理 UI 生命周期、事件订阅、数据转换。
约束:
- 继承 `UIFormControllerCommonBase<TContext, TForm>`
- 命名:`XXXFormController`
- 通过 `BindUseCase(IUIUseCase)` 注入用例并做类型校验
- `OpenUI(object userData = null)` 支持:`Context`、`RawData`、`null`
- 负责 RawData -> Context 的转换(常见 `BuildContext`)
- 在 `SubscribeCustomEvents / UnsubscribeCustomEvents` 成对管理事件
- 可做局部刷新(避免整窗重建)
参考:
- `Assets/GameMain/Scripts/UI/GameScene/Controller/ShopFormController.cs`
- `Assets/GameMain/Scripts/UI/GameScene/Controller/LevelUpFormController.cs`
- `Assets/GameMain/Scripts/UI/MenuScene/Controller/SelectRoleFormController.cs`
### 3.4 Context 层
职责:承载“可直接驱动 UI 展示”的上下文数据。
约束:
- 继承 `UIContext`
- 命名:`XXXFormContext` 或 `XXXItemContext`
- 字段以展示友好为目标(标题、描述、图标、稀有度、列表等)
- 允许组合子 Context(例如列表区 + 条目)
参考:
- `Assets/GameMain/Scripts/UI/GameScene/Context/ShopFormContext.cs`
- `Assets/GameMain/Scripts/UI/GameScene/Context/DisplayListAreaContext.cs`
- `Assets/GameMain/Scripts/UI/MenuScene/Context/SelectRoleFormContext.cs`
### 3.5 View 层
职责:纯表现层,负责控件绑定、显示刷新、交互事件抛出。
约束:
- Form 类继承 `UGuiForm`,子组件通常继承 `MonoBehaviour`
- 命名:`XXXForm` / `XXXItem` / `XXXArea`
- 提供 `RefreshUI(Context)`、`OnInit(Context)`、`OnReset()` 等渲染入口
- 用户交互通过 `GameEntry.Event.Fire(...)` 通知 Controller
- 不承载业务规则(计算、流程推进、数据筛选应在 UseCase)
参考:
- `Assets/GameMain/Scripts/UI/GameScene/View/ShopForm.cs`
- `Assets/GameMain/Scripts/UI/GameScene/View/DisplayListArea.cs`
- `Assets/GameMain/Scripts/UI/MenuScene/View/SelectRoleForm.cs`
## 4. 标准交互流程
### 4.1 初始化与绑定
1. Procedure/GameState 创建 UseCase
2. 调用 `GameEntry.UIRouter.BindUIUseCase(UIFormType.X, useCase)`
示例:
- `Assets/GameMain/Scripts/Procedure/Game/GameStateShop.cs`
- `Assets/GameMain/Scripts/Procedure/Game/GameStateLevelUp.cs`
- `Assets/GameMain/Scripts/Procedure/ProcedureStartMenu.cs`
### 4.2 打开 UI
1. 调用 `GameEntry.UIRouter.OpenUI(UIFormType.X)`
2. Controller 从 UseCase 取 RawData(或接收外部 RawData/Context)
3. Controller 构建 Context 后打开/刷新 Form
4. View 在 `OnOpen` 中校验 Context 类型并执行 `RefreshUI`
### 4.3 用户交互到刷新
1. View 触发事件(如购买、刷新、选择)
2. Controller 监听事件并调用 UseCase
3. UseCase 返回新数据或操作结果
4. Controller 更新 Context 并刷新全部或局部 UI
### 4.4 关闭 UI
1. 调用 `GameEntry.UIRouter.CloseUI(UIFormType.X)`
2. Controller 解除事件订阅并关闭窗体
3. View `OnClose` 清理本地状态
## 5. 目录与命名规范
- 目录:`UI/<SceneDomain>/RawData|UseCase|Controller|Context|View`
- 五层同名前缀保持一致:`ShopForm*`、`LevelUpForm*`、`SelectRoleForm*`
- 子组件上下文命名:`RoleItemContext`、`DisplayItemContext`、`LevelUpRewardItemContext`
- 新增 UI Form 时优先建立完整五层;仅纯静态展示可降级为 View-only
## 6. 依赖方向约束
允许依赖:
- `UseCase -> RawData / 领域对象`
- `Controller -> UseCase + RawData + Context + View + Event`
- `View -> Context + Event`
禁止依赖:
- `View -> UseCase`
- `View -> 领域状态修改`
- `Context/RawData -> View`
## 7. 新增一个五层 UI 的落地步骤
1. 在目标场景目录创建 `RawData / UseCase / Context / Controller / View` 对应类型
2. 在 UseCase 中实现模型创建与交互方法
3. 在 Controller 中实现 `BindUseCase`、`OpenUI`、`BuildContext`、事件订阅
4. 在 View 中实现 `RefreshUI` 和交互事件抛出
5. 在对应 Procedure/GameState 里完成 UseCase 绑定与 Open/Close 调用
6. 自测三条主链路:首次打开、交互刷新、关闭重开
## 8. 项目当前实践说明
- `ShopForm`、`LevelUpForm`、`SelectRoleForm` 是当前五层模式的主要样板
- `DialogForm` 也有 Controller/Context/RawData,但 UseCase 为可选
- `HudForm`、`StartMenuForm` 当前为轻用例场景,可不强制 UseCase
- `SettingForm`、`AboutForm` 属于历史直连型 UI,不属于五层完整样板
---
如后续需要统一重构,建议优先把历史直连型 UI(如 `SettingForm`)迁移到五层模板,以降低 UI 逻辑耦合度。