第2章:离线分层架构整体蓝图:视图、分层结构、组件依赖、数据流向

2.1 架构总览

离线分层架构是Repository模式在资源受限、网络不稳定的终端或边缘场景下的核心落地形态。它将数据访问、缓存、离线同步与业务逻辑严格分离,使每一层只关注自身职责,并通过接口契约进行交互。

整体蓝图可抽象为四层模型:

  • 视图层(View Layer) — 用户交互与UI状态管理。
  • 服务层(Service Layer) — 业务编排、离线策略调度、数据一致性协调。
  • 仓储层(Repository Layer) — 数据访问抽象、缓存策略、离线持久化。
  • 数据源层(Data Source Layer) — 本地数据库、云端API、文件系统等具体存储。

各层之间仅允许上层依赖下层,禁止跨层直接调用或反向依赖,确保架构的单向依赖和信任链路可审计。

2.2 分层职责与边界

层级核心职责对外暴露的边界
视图层渲染UI、收集用户事件、管理页面状态调用服务层接口,不接触任何数据源
服务层业务规则执行、离线策略判断(网络状态/缓存有效期)、数据合并与冲突处理仅依赖仓储层抽象接口
仓储层数据访问统一入口、多级缓存路由、离线写缓冲、数据同步策略通过接口定义与数据源层解耦
数据源层本地持久化(SQLite/LevelDB)、远程API调用、文件存储实现仓储接口,内部可隔离
架构原则:每一层只感知下一层的抽象接口,不关注其具体实现。例如服务层不直接知道数据来自本地缓存还是远程API,从而允许仓储层灵活替换缓存算法或同步机制。

2.3 组件依赖关系

组件间的依赖采用接口注入方式,运行时通过依赖注入容器(如Dagger/Hilt、Kodein)组装。关键依赖链如下:

  • Activity/Fragment → ViewModel → Service → Repository → DataSource
  • Repository内部:CacheDataSource(内存/磁盘) + RemoteDataSource + LocalDataSource
  • 离线同步器(SyncManager)作为服务层组件,依赖仓储层提供的同步接口

为防止循环依赖,严禁仓储层反向依赖服务层,也严禁数据源层引用视图层对象。

2.4 数据流向与控制流

离线读取流程(典型)

  1. 视图层发起数据请求 → 服务层判断是否需要刷新。
  2. 服务层调用仓储层 getItems(),不关心缓存策略。
  3. 仓储层按“先读内存缓存 → 未命中则读本地数据库 → 若还无数据则触发远程获取”的优先级路由。
  4. 远程获取成功后,仓储层更新本地数据库和内存缓存。
  5. 返回数据至服务层,最终推送至视图。

离线写入流程(典型)

  1. 视图层提交写操作 → 服务层校验业务规则。
  2. 仓储层将写操作先写入本地队列(离线写缓冲区),即刻返回成功。
  3. 后台同步器按策略(定时/网络恢复后)从队列取出操作,发送至远程API。
  4. 远程确认后,仓储层更新本地数据库并移除队列条目;若冲突,则触发合并回调。
关键决策:数据写回采用“写本地→异步同步”模式,保证用户操作即时响应,同时避免网络不可用时阻塞。仓储层内部维护一个操作日志用于冲突检测和幂等重放。

2.5 架构视图(SVG)

下方SVG图示展示离线分层架构的整体结构、组件分层、单向依赖箭头以及离线读/写数据流向。

离线分层架构整体蓝图 视图层 UI组件 / ViewModel / State管理 服务层 业务编排 / 离线策略 / 冲突处理 仓储层(Repository) 缓存路由 / 离线写缓冲 / 同步调度 数据源层 本地数据库 / 远程API / 文件系统 离线读取流 View → Service → Repository → 缓存/本地/远程 离线写入流 View → Service → Repository写缓冲 → 异步同步

2.6 选型权衡与风险点

权衡点推荐方案风险提示
缓存一致性仓储层维护版本号,服务层在合并时检查多端同时离线可能引发复杂冲突,需设计幂等合并策略
离线写缓冲区大小使用固定队列(如100条),溢出时触发压缩不合理设置可能导致内存OOM,建议持久化队列
同步粒度按实体类型分别同步,而非全量跨实体事务难以保证,需引入本地事务日志
数据源切换仓储层通过策略模式动态选择数据源频繁切换可能带来性能抖动,需预热连接池
常见反模式:视图层直接访问仓储层或数据源层。这破坏了分层规则,导致业务逻辑泄漏到UI、缓存策略难以替换。必须通过服务层作为中间层。

2.7 落地步骤与验收标准

落地步骤

  1. 定义仓储接口(Repository Interface),包含CRUD与会话无关的方法签名。
  2. 实现数据源层:本地数据库(如Room/Realm)、远程API(Retrofit/Ktor)。
  3. 构建仓储层实现:内存缓存+本地持久化+远程数据源的路由逻辑,以及离线写缓冲队列。
  4. 实现服务层:调用仓储接口,注入离线同步器,处理业务规则。
  5. 视图层通过依赖注入获取服务层实例,不再直接接触任何数据源。

验收标准

  • 离线状态下,所有读操作返回本地缓存或本地数据库数据,无崩溃、无白屏。
  • 离线状态下,写操作被安全放入本地缓冲队列,应用重启后不丢失。
  • 网络恢复后,缓冲队列在30秒内触发同步,同步结果正确。
  • 仓储层接口替换测试:更换本地数据库为文件存储后,服务层和视图层无需改动。
推荐工具:仓储层可使用MapStore模式(类似kotlinx.collections.immutable)或现成的缓存框架(如Caffeine),但需确认其支持离线缓存生命周期管理。

2.8 信任链路与审计要点

每一层必须验证来自上层的输入参数,但信任链只能向下传递:

  • 服务层信任视图层的调用意图(如用户已认证),但不信任数据有效性,需校验参数。
  • 仓储层信任服务层提供的上下文(如用户ID),但不信任缓存条目是否过期,需检查TTL。
  • 数据源层信任仓储层的查询参数,但不信任SQL注入风险,需使用参数化查询。

离线环境下的审计日志应当记录:数据获取来源(本地/远程)、缓存命中率、写缓冲队列长度、同步冲突次数,以支持后续架构调优。