第2章 核心概念与术语:ViewModel边界、状态所有权、隔离域、公共状态总线、副作用容器

本章明确定义构成跨模块状态隔离体系的五个核心概念,并围绕它们建立统一的术语框架。每个概念既是架构决策的原子单元,也是后续章节中分层策略、数据流设计和风险控制的讨论基础。理解这五个概念及其关系,是掌握整套隔离方法的前提。

核心要点:五个概念形成一个闭环——隔离域划定范围,ViewModel边界定义守卫规则,状态所有权确立归属,公共状态总线实现受控共享,副作用容器管理不可控操作。任何跨模块状态问题都可以用这五个概念拆解。
跨模块ViewModel边界状态隔离 — 核心概念架构 公共状态总线 (Public State Bus) 隔离域 A (Isolation Domain A) 状态所有权 A (State Ownership A) ▌ ViewModel 边界 (内部守卫) 隔离域 B (Isolation Domain B) 状态所有权 B (State Ownership B) ▌ ViewModel 边界 (内部守卫) 跨域屏障 ✕ 禁止直接跨域 副作用容器 (Side Effect Container) 图2-1 概念关系说明:每个隔离域拥有独立的ViewModel边界和状态所有权;跨域状态必须经过公共状态总线;所有副作用统一由容器管理。 中间屏障表示「ViewModel边界」禁止模块间直接读写对方状态,强制走总线。

2.1 边界定义:ViewModel边界

ViewModel边界是跨模块状态隔离的第一道防线。它不是一个物理接口或抽象类,而是一组约定 + 校验 + 强制规则的组合,用于限定一个ViewModel可以访问哪些状态、可以被哪些外部模块订阅、以及状态变更的传播范围。

  • 物理表现:在代码层面表现为模块级的 internal / package-private 可见性 + 运行时边界检查。
  • 核心规则:任何状态离开所属隔离域前,必须显式声明到公共状态总线;任何外部读请求必须经过总线代理。
  • 违反后果:导致状态突变溯源丢失、跨模块耦合、难以测试和回滚。
鉴别技巧:在代码审查中,如果发现模块A直接调用了模块B的ViewModel内部方法或直接读取其LiveData/StateFlow,就说明ViewModel边界已被突破,需要重构。

2.2 分层策略:隔离域与状态所有权

隔离域是状态存在的容器,状态所有权是容器内每个状态片段的归属标签。两者共同构成分层策略的基础。

层次元素职责示例
域层隔离域划定状态生存范围,禁止外部直接访问“用户模块域”
归属层状态所有权每个状态片段有且仅有一个所有者“UserProfileViewModel”
守卫层ViewModel边界在域边界执行读写校验边界守卫策略

分层原则:隔离域可以包含多个ViewModel,但每个状态片段必须明确归属于唯一的ViewModel。所有权不可模糊,不可共享。

常见误区:团队成员常把「隔离域」等同于「模块文件夹」,这是错误的。隔离域是运行时概念,不是编译期目录结构。同一个模块内可以存在多个隔离域,只要它们不共享可变状态。

2.3 组件职责:五概念职责矩阵

概念核心职责生命周期跨模块可见性错误处理角色
ViewModel边界守卫状态,阻止非法越域读写与隔离域相同对域外不可见越界拒绝 + 日志
状态所有权标记状态归属,确保单点修改与ViewModel相同仅通过代理暴露所有权冲突检测
隔离域提供状态容器和边界环境模块启动 ~ 销毁域间隔离域故障熔断
公共状态总线跨域状态发布 / 订阅应用全局全局可见广播失败重试
副作用容器统一管理网络、DB、定时器等副效应与隔离域绑定或全局通过总线回传结果副作用超时兜底

2.4 数据流 / 控制流 / 信任链路

五个概念之间的交互遵循严格的信任链路:

  1. 数据流:状态 只允许 从「状态所有权」→「ViewModel边界」→「公共状态总线」→ 其他隔离域。不允许直接跨域推送。
  2. 控制流:动作指令从「外部」→「公共状态总线」→「目标隔离域边界」→「状态所有权」→ 执行。边界守卫在入口处校验权限。
  3. 信任链路:每个隔离域只信任自己的ViewModel边界和公共状态总线;不信任其他隔离域的任何直接调用。
// 伪代码:跨域状态读取的信任链路示意
// 不允许: ModuleA.viewModel.state -> 直接 -> ModuleB
// 允许:   ModuleA  -> 总线.read("user/name")  ->  边界校验  ->  所有权返回

2.5 选型权衡

场景推荐策略备选方案权衡点
同模块跨ViewModel共享隔离域 + 内部事件总线直接依赖隔离性 vs 开发效率
跨模块强一致状态公共状态总线 + 状态所有权显式声明全局单例可追溯性 vs 性能开销
高频副作用(如位置上报)副作用容器 + 批量回写分散在各ViewModel集中管控 vs 灵活性
遗留系统迁移先建边界屏障,逐步收拢所有权一次性重构渐进安全 vs 周期长
决策建议:优先保证「状态所有权」清晰,再考虑「公共状态总线」的性能优化。所有权模糊是架构腐化的第一信号。

2.6 风险点

  • 边界穿透:开发者为图方便直接调用其他模块ViewModel内部方法,导致边界名存实亡。
  • 所有权漂移:同一状态被多个ViewModel修改,失去单一可信源。
  • 总线过载:所有跨域通信都走总线,导致事件爆炸、调试困难。
  • 副作用逃逸:副作用直接在ViewModel中执行,绕过容器管理,造成测试困难和内存泄漏。
  • 隔离域泄露:隔离域内部状态通过回调或监听器泄漏到域外。

2.7 落地步骤

  1. 盘点现状:梳理当前模块间所有直接的状态读写依赖,标记越界点。
  2. 划定隔离域:按业务模块或功能簇划分隔离域,明确每个域的边界。
  3. 声明状态所有权:为每个状态片段指定唯一的所属ViewModel。
  4. 引入公共状态总线:建立跨域状态发布/订阅机制,替换直接依赖。
  5. 建立副作用容器:将网络、DB、定时器等统一收容到容器中。
  6. 添加边界守卫:在隔离域入口处增加运行时校验或编译期可见性限制。

2.8 验收标准

验收项验证方式通过条件
边界完整性代码扫描 + 运行时日志无直接跨域ViewModel调用
所有权唯一性静态分析每个状态字段仅被一个ViewModel修改
总线合规性链路追踪所有跨域读/写均经过总线
副作用归仓单元测试覆盖ViewModel单元测试中无真实IO
隔离域自愈故障注入单域崩溃不影响其他域状态
快速自检:如果团队新成员能在30分钟内说出当前模块的「隔离域划分数」「每个域的状态所有权归属」「总线使用的三个典型场景」,说明概念落地合格。

本章定义的五个核心概念将贯穿整个课程。第3章将在此基础上,展开分层状态架构的具体设计模式。