Files
FlowScope/docs/reviews/flowscope-framework-review.md
2026-05-21 11:28:56 +08:00

260 lines
12 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.
# FlowScope 框架评审文档
评审日期2026-05-19
评审对象:`My project/Assets/FlowScope`
评审范围Runtime、Tests、Samples、asmdef、核心服务实现与测试覆盖
评审结论:建议有条件通过,定位为 P0/P1 阶段轻量 Unity 游戏基础框架
## 1. 总体结论
FlowScope 当前已经具备一个轻量游戏框架的基本形态,适合用于小型项目、原型项目或作为后续框架演进的 P0 基座。它的优势在于分层清晰、抽象克制、测试意识较好,并且围绕 Unity 常见横切能力建立了可替换接口。
当前不建议直接定义为稳定生产框架。主要原因是运行时对象销毁、自研 JSON 转换器、AOT/linker 验证和真实 Unity Test Runner 验收仍存在生产风险。这些问题不影响它作为框架雏形继续推进,但应作为进入生产复用前的前置整改项。
## 2. 技术基线
- Unity 版本:`2022.3.62f2c1`
- 主要依赖:
- `com.cysharp.r3`
- `org.nuget.r3`
- `com.unity.ugui`
- `com.unity.textmeshpro`
- `com.unity.timeline`
- 目录结构:
- `Runtime`:框架运行时代码
- `Tests/EditMode`:编辑器测试
- `Tests/PlayMode`:运行时测试
- `Samples/MainMenuP0`P0 示例场景与示例业务
- asmdef
- `FlowScope.Runtime`
- `FlowScope.Tests.EditMode`
- `FlowScope.Tests.PlayMode`
- `FlowScope.Samples.MainMenuP0`
## 3. 现有模块评价
### 3.1 Flow
代表文件:`Runtime/Flow/GameFlow.cs`
`GameFlow` 负责 Feature 生命周期编排,包括启动、切换、关闭、失败清理和状态保护。整体职责清晰,和 `IFeature``FeatureContext` 的边界较自然。
优点:
- 状态机明确,避免非法状态调用。
- Feature 使用独立 scope便于做生命周期隔离。
- 失败路径中有资源、容器、Feature 的清理逻辑。
- 测试覆盖了启动、切换、关闭、失败和取消场景。
风险:
- `StartupAsync` 固定依赖 `IConfigProvider.LoadAllAsync`,会让无配置项目、分包配置、热更新配置的启动流程不够灵活。
- `GameFlow` 当前更像“启动编排器 + Feature 生命周期管理器”的混合体,后续业务复杂时可能需要把配置加载职责移回 Bootstrap。
评价:结构良好,建议保留为框架核心,但需要降低对配置加载的硬绑定。
### 3.2 Container
代表文件:`Runtime/Container/Container.cs`
自研容器实现轻量支持实例注册、singleton factory、scoped、transient、父子容器、循环依赖检测和拥有对象释放。
优点:
- API 简单,学习成本低。
- scope 模型适合 Feature 生命周期。
- dispose 顺序和循环依赖都有测试。
- 没有引入大型 DI 框架,符合轻量框架定位。
风险:
- `GeneratedFactories` 需要外部注册,长期需要配套生成器或明确手写规范。
- 反射工厂适合开发期,但移动端/AOT 环境需要持续验证。
- `RegisterFactory` 仍保留为旧式 lazy singleton 兼容入口,需要避免在新代码中用于 Feature/ViewModel/短生命周期对象。
评价P0/P1 阶段可接受。后续重点不是扩大能力,而是保持生命周期语义稳定、写清注册规范和 AOT 策略。
### 3.3 Resources
代表文件:`Runtime/Resources/ResourceService.cs``Addressables/AddressablesResourceBackend.cs`
资源层抽象了 `IResourceService``IResourceHandle<T>``IResourceGroup``IResourceBackend`Runtime 核心负责共享加载、引用计数和分组释放Addressables 适配位于独立 asmdef。
优点:
- 使用句柄释放资源,方向正确。
- 支持同 key 同类型加载去重。
- `ResourceGroup` 适合跟随 Feature 生命周期批量释放。
- EditMode / PlayMode 测试覆盖了复用、引用计数、取消等待和完成后释放等路径。
风险:
- Addressables 真实 load/release 仍缺少最小集成测试资源。
- 取消等待后底层共享加载仍会继续执行,这是设计选择;需要继续用测试保护“所有等待者取消后完成即释放”的语义。
评价抽象方向正确Runtime 核心与 Addressables 适配层已经拆开;下一步重点是真实 Addressables 集成验收。
### 3.4 UI
代表文件:`Runtime/UI/UIManager.cs`
UI 模块基于 `UIPanelAttribute` 标记层级和路径,通过 `UIManager` 加载 prefab、挂载到 Canvas、绑定 ViewModel并支持 Destroy/Cache 策略。
优点:
- 使用 Attribute 降低打开面板时的字符串散落。
- 支持按层关闭、关闭全部、缓存复用。
- 打开失败时有句柄释放和实例销毁逻辑。
- PlayMode 测试覆盖了路径、层级、缓存、关闭顺序和 Bind 失败。
风险:
- 运行时代码使用 `DestroyImmediate`,不适合常规 PlayMode/Runtime 生命周期。
- 面板路径约定较隐式,需要文档约束或配置化。
- 当前只允许关闭栈顶面板,适合简单 UI但复杂弹窗管理可能需要更细的策略。
评价:可作为 P0 UI 管理器,但 `DestroyImmediate` 应优先修正。
### 3.5 Audio
代表文件:`Runtime/Audio/AudioService.cs`
音频模块提供 BGM、SFX、音量、静音、淡入淡出和 SFX 池。
优点:
- 接口简单,适合快速接入。
- SFX 池和复用策略清楚。
- PlayMode 测试覆盖了播放、停止、池耗尽、音量和淡入淡出。
风险:
- 同步播放 API 只适合读取已经预加载或已完成的资源;调用者如果误用未预加载资源,会得到明确异常而不是阻塞等待。
- 音频服务是 `MonoBehaviour`,但依赖通过 `Initialize` 注入,需要文档明确创建流程。
- 新业务仍应优先使用 `PlayBgmAsync` / `PlaySfxAsync`,避免把同步 API 当作资源加载入口。
评价:功能够用,旧的同步阻塞风险已降低;生产复用前仍需继续明确同步 API 的使用边界。
### 3.6 Save / Config / Data
代表文件:
- `Runtime/Save/SaveService.cs`
- `Runtime/Config/JsonConfigProvider.cs`
- `Runtime/Data/ReactivePropertyJsonConverter.cs`
数据相关模块围绕 R3 的 `ReactiveProperty` 做了 JSON 序列化、存档读写和配置加载。
优点:
- Save 的 storage 和 serializer 可替换。
- Config 支持多表加载和重复 id 检查。
- Data 层能处理 `ReactiveProperty<T>`,契合 R3 数据模型。
- 相关 EditMode 测试较完整。
风险:
- JSON parser/serializer 是自研实现,长期边界成本较高。
- 当前更适合简单 DTO不适合复杂对象图、版本迁移、字段重命名、特殊字符完整兼容等场景。
- `GetAll<T>` 返回新 List顺序来自 Dictionary values不应作为稳定排序依赖。
评价P0 可以使用,但应明确“简单数据模型”边界。生产化建议接入成熟 JSON 库,保留 R3 适配层。
## 4. 测试覆盖评价
现有测试覆盖优于一般框架雏形,尤其是:
- `GameFlowTests` 覆盖生命周期和异常清理。
- `ContainerTests` 覆盖注册、scope、dispose、循环依赖。
- `UIManagerTests` 覆盖 UI 打开、关闭、缓存和异常。
- `AudioServiceTests` 覆盖播放、停止、池和音量。
- `SaveServiceTests``JsonConfigProviderTests``DataSerializationTests` 覆盖数据链路。
仍建议补充:
- Addressables 真实包接入测试或集成验证。
- AOT/linker 场景验证。
- UI 使用 `Destroy` 后的帧级测试调整。
- 音频异步加载接口改造后的取消、失败和重复播放测试。
- Config/Save 数据版本迁移测试。
## 5. 主要风险清单
| 优先级 | 风险 | 影响 | 建议 |
| --- | --- | --- | --- |
| P0 | Runtime 使用 `DestroyImmediate` | 运行时生命周期不稳 | 改为 `Destroy`,测试按帧等待 |
| P1 | Addressables 真实集成测试不足 | 适配层编译通过不等于真实 load/release 验收通过 | 增加最小 Addressables 测试资源或人工验收步骤 |
| P1 | 自研 JSON 转换器 | 边界和维护成本高 | 明确 DTO 限制或接入成熟 JSON 库 |
| P1 | `GameFlow` 固定加载配置 | 启动流程不够弹性 | 配置加载移到 Bootstrap 或可选策略 |
| P2 | `RegisterFactory` 兼容入口仍可能误用 | 使用者可能把 lazy singleton 用于短生命周期对象 | 新代码使用 `RegisterSingletonFactory` / `RegisterScoped` / `RegisterTransient` |
## 6. 审批意见
结论:有条件通过。
通过范围:
- 可继续作为 FlowScope P0/P1 基础框架推进。
- 可用于示例项目、小型原型项目和内部验证项目。
- 可作为后续 Runtime 包化、模块拆分和 API 稳定化的基础。
限制条件:
- 暂不建议标记为生产稳定版本。
- 暂不建议在多人长期项目中无约束扩散使用。
- 在进入生产复用前,必须完成 P0 风险整改。
前置整改项:
1.`UIManager` 运行时销毁逻辑从 `DestroyImmediate` 调整为 `Destroy`
2. 为 Addressables 适配增加真实 load/release 最小验收。
3. 明确 Config/Save DTO 与 AOT/linker 限制。
4. 在进入 P2 包分发前补一次 Unity Test Runner 全量验收记录。
## 7. 后续建议
短期建议:
- 先修生命周期和异步资源问题,不急于扩展新模块。
- 保持框架轻量,不引入事件总线、复杂状态机编辑器、大型 DI 等重能力。
- 将 Samples 继续作为验收样板,所有框架规则都应能在 Sample 中体现。
中期建议:
- 将 Runtime 拆为核心层和适配层,例如 `FlowScope.Runtime``FlowScope.Addressables`
- 为容器工厂生成建立明确流程,降低手写注册成本。
- 给 Save/Config 增加数据版本和迁移策略。
长期建议:
- 明确 FlowScope 的定位:小型游戏基础设施,而不是全能游戏引擎框架。
- API 稳定后再考虑 package 化和跨项目复用。
- 保持测试先行,所有生命周期规则和失败路径都应有测试保护。
## 8. 最终评级
| 维度 | 评级 | 说明 |
| --- | --- | --- |
| 架构清晰度 | 良好 | 模块边界清楚,抽象克制 |
| 可测试性 | 良好 | 已有较完整 EditMode/PlayMode 测试 |
| Unity 生命周期安全 | 一般 | `DestroyImmediate` 与 Unity Test Runner 验收仍需收口 |
| 生产稳定性 | 一般 | 仍处于 P0/P1 框架雏形 |
| 可演进性 | 良好 | 适合继续拆模块、补规范、稳定 API |
综合评级B+。
结论摘要FlowScope 是一个有工程意识的轻量 Unity 框架骨架,值得继续推进;但在正式生产复用前,需要优先修正运行时销毁、真实 Addressables 验收和 AOT/JSON 边界三个关键问题。
# P1 更新记录2026-05-20
P1 已完成第一批生产化硬化,评审风险状态同步如下:
| 原风险 | P1 状态 | 说明 |
| --- | --- | --- |
| Addressables 反射调用 | 已降低 | Addressables 适配已从 Runtime 核心拆出到 `FlowScope.Addressables` 独立 asmdef核心资源系统通过 `IResourceBackend` 工作。包解析与生成项目编译阻塞已解除,仍缺真实 load/release 验收。 |
| 自研 JSON 转换器缺少扩展点 | 已降低 | Config 增加 `IConfigSource` / `IConfigParser`Save 增加版本 envelope 与 `ISaveMigration` 链。长期是否替换成熟 JSON 库仍是 P2 决策。 |
| UI 缺少轻量导航与预加载 | 已降低 | 新增 `UIScreenNavigator``UIPreloadService`,并补充 PlayMode 编译级测试。 |
| 样例不能体现生产化装配 | 已降低 | MainMenuP0 已改为 P1 装配方式,覆盖启动、点击、保存恢复和资源释放。 |
| Package/editor tooling | 保持 P2 | 本轮没有做包分发、编辑器工具和跨项目模板化。 |
当前结论仍是“有条件通过”P1 代码与文档已落地P2 前整改已收束 Container/Feature 生命周期、样例 Bootstrap 启动模型、资源取消与 UI 预加载边界;完整 Unity Test Runner 和人工场景验收仍需补跑。