Android架构疑问:RemoteMediator是否为Repository的DataSource?及Pager用法确认
关于Jetpack Paging中RemoteMediator在Repository里的正确用法
你的两种写法都有各自适用场景,但从可测试性、单一职责和依赖注入规范来看,更推荐将DatasRemoteMediator作为构造参数传入Repository,而非在getDatasStream方法内创建。
1. 当前写法(方法内创建)的优缺点
- 优点:实现简单,适合快速原型开发,无需额外配置依赖注入。
- 缺点:
- 单元测试困难:
DatasRemoteMediator在方法内硬编码创建,无法替换为Mock实例来隔离测试。 - 职责混淆:Repository本应专注数据聚合逻辑,现在还要负责创建RemoteMediator,违反单一职责原则。
- 扩展性差:后续修改RemoteMediator的依赖(比如更换NetworkDataSource实现),必须改动Repository方法内部代码。
- 单元测试困难:
2. 构造注入写法的优势
- 可测试性强:能轻松传入Mock版
DatasRemoteMediator,单独测试Repository的分页逻辑,无需依赖真实网络或数据库。 - 职责清晰:Repository只负责通过Pager暴露分页数据流,RemoteMediator的创建和依赖管理交给上层(比如DI容器)处理,符合单一职责。
- 扩展性好:后续调整RemoteMediator的实现或依赖时,无需修改Repository代码,仅调整注入配置即可。
3. 代码示例参考
推荐的构造注入方式
class DataRepository( private val remoteMediator: DatasRemoteMediator, private val localDataSource: LocalDataSource, private val pagingConfig: PagingConfig = PagingConfig(pageSize = 20) ) { fun getDatasStream(): Flow<PagingData<Data>> { return Pager( config = pagingConfig, remoteMediator = remoteMediator, pagingSourceFactory = { localDataSource.getPagingSource() } ).flow } }
方法内创建的方式(仅适合快速原型)
class DataRepository( private val networkDataSource: NetworkDataSource, private val localDataSource: LocalDataSource, private val mapper: DataMapper, private val pagingConfig: PagingConfig = PagingConfig(pageSize = 20) ) { fun getDatasStream(): Flow<PagingData<Data>> { val remoteMediator = DatasRemoteMediator( networkDataSource = networkDataSource, localDataSource = localDataSource, mapper = mapper ) return Pager( config = pagingConfig, remoteMediator = remoteMediator, pagingSourceFactory = { localDataSource.getPagingSource() } ).flow } }
额外注意点
- RemoteMediator的核心职责是协调本地数据库与网络数据的同步,它本身应依赖NetworkDataSource、LocalDataSource和映射器,而非让Repository传递这些依赖。
- 如果使用Hilt等依赖注入框架,构造注入的方式更契合框架规范,能自动处理RemoteMediator的实例创建与生命周期管理。
内容的提问来源于stack exchange,提问作者JJ86
相关产品推荐
相关产品推荐

