Back to Gsy Github App Flutter

ADR-0001 状态管理收敛策略

docs/06-decisions/ADR-0001-状态管理收敛策略.md

8.0.03.3 KB
Original Source

ADR-0001 状态管理收敛策略

状态

已采纳

日期

2026-03-10

背景

当前项目同时使用 Redux、Riverpod、Provider、Signals。 这种并存状态来自历史演进和教学展示诉求,短期内不会也不应该通过一次重构强行统一。

问题不在于“有多种状态管理”,而在于如果没有新增规则,后续功能和 agent 改动会继续把边界变得更混乱:

  • 新功能可能按个人偏好继续引入不一致方案
  • 页面局部状态可能误上升为全局状态
  • 全局状态可能同时在多个状态容器里重复保存
  • AI 在缺少明确规则时容易用“看起来最熟的库”去实现需求

决策

项目接受当前多状态并存的现实,但从现在开始约束新增和演进规则:

  1. 不新增第五种状态管理方案
  2. 无关任务不得顺手迁移既有模块的状态管理
  3. 新增状态默认按“作用域”选择,而不是按个人偏好选择
  4. 涉及全局共享状态时,优先使用现有全局主路径,而不是新开一条平行状态链路
  5. 任何跨模块状态管理迁移都必须先补决策记录,再执行代码改造
  6. 未经明确允许,不得为了满足需求或修复问题,擅自把模块从既有框架/状态实现切换到另一套实现

默认选择规则

应用级共享状态

适用场景:

  • 登录态
  • 当前用户核心信息
  • 全局主题、语言、灰度模式
  • 会影响多个页面和全局入口的状态

默认策略:

  • 优先复用当前已经承接这类职责的 Redux 或 Riverpod 入口
  • 如果是“纯应用配置型共享状态”,优先贴近现有 Riverpod 方式
  • 如果是历史上已经由 Redux 管理的登录/用户链路,优先延续 Redux

功能级共享状态

适用场景:

  • 某个复杂功能模块内部多个子页面、tab、局部组件共享状态

默认策略:

  • 优先沿用该模块当前已存在方案
  • 对当前仓库,像 repos 这类跨 tab 共享状态,继续沿用模块内 Provider 结构

页面局部交互状态

适用场景:

  • 筛选条件
  • 页码
  • 局部开关
  • 临时 UI 控制状态

默认策略:

  • 优先使用页面本地 state
  • 如果模块已经明确使用 Signals 或局部 Riverpod,则跟随既有模式

不做的事

  • 不要求立即把 Redux/Provider/Signals 全部迁到 Riverpod
  • 不要求为了一致性重写成熟模块
  • 不鼓励在普通需求里夹带架构收敛
  • 不允许为了“更容易改”就把演示性质明确的模块偷偷改成别的状态方案

影响

正面影响:

  • 新增功能不会继续无序扩散状态方案
  • agent 更容易判断应该把状态放在哪里
  • 评审时有了明确基准,而不是只看个人习惯

代价:

  • 一段时间内项目仍会维持多种状态管理并存
  • 部分历史模块看起来仍然不统一

执行规则

以下情况需要先补新 ADR,再开始迁移:

  • 计划将某一整个功能域从 Provider 迁到 Riverpod
  • 计划把登录和用户主链路从 Redux 挪走
  • 计划修改全局状态入口,影响 lib/app.dart

普通需求只需遵守本 ADR,不需要额外发起架构迁移。

额外约束:

  • 如果某个模块明确承担演示某种状态方案的职责,例如 notify 中的 Signals,用普通需求绕过这层设计同样视为越界。