第4章 Repository模式架构图:组件关系、数据流、调用链
4.1 边界与分层
Repository 模式在 Android 架构中处于 数据访问层(DAL) 与 业务层 之间的边界位置。它不直接操作数据库或网络,而是通过抽象接口将数据来源(本地 Room、远程 API、缓存)统一暴露给上层调用方。
| 层次 | 组件 | 边界职责 |
|---|---|---|
| 业务/用例层 | ViewModel / UseCase | 调用 Repository 接口,不感知数据来源 |
| 数据访问抽象层 | Repository 接口 | 定义数据获取/写入契约,隔离存储实现 |
| 数据访问实现层 | RepositoryImpl / Room DAO | 实现接口,协调本地/远程数据源 |
| 持久化层 | Room 数据库 / SQLite | 提供本地存储能力,DAO 负责具体操作 |
边界原则:Repository 不得依赖 ViewModel 或 Android 生命周期组件;DAO 不得暴露给业务层,只能通过 Repository 接口访问。
4.2 组件职责
- Repository 接口:定义如
fun getUsers(): Flow<List<User>>的契约,无任何实现细节。 - RepositoryImpl:实现接口,注入 DAO 和网络数据源,决定“从本地读还是从网络取”的策略。
- Room DAO:直接操作数据库,返回
Flow或LiveData,只负责 SQL 操作。 - ViewModel:持有 Repository(依赖反转),调用方法并观察数据流。
- 数据源(可选):如 Retrofit API、内存缓存,作为 Repository 的次要数据源。
4.3 数据流、控制流与信任链路
数据流方向:ViewModel → Repository 接口 → RepositoryImpl → DAO → Room Database。数据以 Flow 或挂起函数形式回流。控制流(命令流)同样沿此链路向下,但 Repository 内部可能根据策略(如网络优先/缓存优先)额外触发网络请求。
信任链路:每一层仅信任下一层提供的契约。ViewModel 信任 Repository 接口返回的数据格式,不信任其是否为本地或远程;Repository 信任 DAO 返回的数据一致性;DAO 信任 Room 持久化正确性。信任边界在每个接口定义处。
4.4 选型权衡
| 方案 | 优点 | 缺点 |
|---|---|---|
| 直接使用 DAO(无 Repository) | 代码量少,快速原型 | 业务层耦合数据库细节;无法统一多数据源;单元测试困难 |
| 使用 Repository 接口 + 实现 | 解耦、可测试、可替换数据源 | 增加接口与实现类;过度抽象可能降低可读性 |
| Repository 泛型化 | 减少重复代码 | 复杂泛型边界难维护;不同类型数据源策略不同时反而耦合 |
常见风险:1) Repository 变成“上帝对象”集中所有数据逻辑;2) 过度封装使得链路过长,调试困难;3) 未处理好网络/本地数据源冲突(版本冲突、TTL 策略)导致数据不一致。
4.5 落地步骤
- 定义 Repository 接口:根据用例,提取出所需数据操作(如
getItem、saveItem)。 - 创建 RepositoryImpl:实现接口,注入 DAO 和可选网络数据源,使用
suspend或Flow封装异步。 - 在 ViewModel 中依赖注入 Repository 接口:通过 Hilt / Koin 或手动构造器注入。
- 编写单元测试:Mock Repository 接口,验证 ViewModel 行为;Mock DAO,验证 Repository 数据合并逻辑。
- 添加数据源策略(可选):如网络优先+缓存过期策略,在 RepositoryImpl 中实现。
4.6 验收标准
- 业务层代码不出现任何 DAO 或 Room 引用。
- Repository 接口可以替换为 Fake 实现,无需改动 ViewModel。
- 更替数据源(如本地改远程)只需修改 RepositoryImpl,不需修改其他层。
- 调用链路清晰:每层只依赖下一层接口,不越层调用。
4.7 组件关系、数据流与调用链示意
SVG 解读:上方分层背景表示各层级,节点为具体组件。实线箭头表示调用链/控制流,虚线箭头表示实现关系与数据流回返。RepositoryImpl 同时对接 Room DAO(本地)与网络数据源(远程),体现多数据源协调能力。信任链路说明框强调契约边界。