Skip to content

数据层

app/src/main/java/com/joker/kit/core/data 将“数据访问”从业务层中抽离出来,以仓库(Repository)模式统一包装不同来源(Network / Database / DataStore)。上层 Feature 只和仓库打交道,而不直接依赖 Retrofit、Room 或 DataStore,从而实现解耦与可替换。

模块结构

目录说明
repository/暴露给业务层使用的仓库。每个仓库可组合多个数据源(网络、数据库、本地存储等),并通过依赖注入交给调用方。

仓库内部再组合以下能力(分别在其他 Core 模块内定义):

  • network.datasource.*:封装各个接口模块(auth/goods/userinfo…),返回 NetworkResponse
  • database.datasource.*:Room 数据访问层。
  • datastore.datasource.*:首选项/kv 等本地配置存储。

仓库类型与职责

仓库主要数据源作用
AuthRepositoryAuthNetworkDataSource负责登录等网络请求,输出 Flow<NetworkResponse<Auth>>
AuthStoreRepositoryAuthStoreDataSource (DataStore)统一维护 Token/登录信息的本地读写,封装“是否登录”“是否需要刷新”等判断。
GoodsRepositoryGoodsNetworkDataSource商品相关接口,包含分页、详情请求。示例用途:展示如何用 Repository 接 Remix Flow;如业务不需要可删除或替换成自有模块。
UserInfoRepositoryUserInfoNetworkDataSource请求用户信息的远程接口。
UserInfoStoreRepositoryUserInfoStoreDataSource (DataStore)缓存/更新本地用户资料,提供便捷获取头像、昵称等能力。
DemoRepositoryDemoDataSource (Room)示例数据库操作,演示如何封装增删改查及 Flow 监听;可按项目需要裁剪或替换成真实表。

Tip:仓库命名统一以 Repository 结尾,若主要职责是本地缓存,则补充 StoreRepository 以示区分。

设计约定

  • Flow 输出:网络/数据库接口统一返回 Flow,方便与 BaseNetWorkViewModel/BaseNetWorkListViewModel 对接;耗时操作默认切换到 Dispatchers.IO
  • 单一入口:ViewModel 不直接依赖 DataSource,而是依赖 Repository,这样可以在仓库内部决定“先读本地再读网络”或“写入数据库后再通知 UI”。
  • 依赖注入:所有仓库通过 Hilt @Inject 构造函数注入,其依赖(DataSource/DAO)也由 Hilt 提供,便于替换与测试。
  • 线程与作用域:耗时操作在仓库内部切到 IO 线程,避免上层忘记处理;需要事务或组合多个源时,也在仓库层封装。
  • 数据合并策略:可以在仓库中增加缓存策略,例如优先读取 DataStore/Room,再触发网络刷新;当前示例仓库保持最小实现,方便在项目扩展时参考。

使用示例

(以 GoodsRepository 为例)

kotlin
@HiltViewModel
class GoodsSearchViewModel @Inject constructor(
    navigator: AppNavigator,
    userState: UserState,
    private val goodsRepository: GoodsRepository,
) : BaseNetWorkListViewModel<Goods>(navigator, userState) {

    init { initLoad() }

    override fun requestListData(): Flow<NetworkResponse<NetworkPageData<Goods>>> {
        val request = GoodsSearchRequest(keyword = currentKeyword, page = currentPage, size = pageSize)
        return goodsRepository.getGoodsPage(request)
    }
}

调用方仅需感知 GoodsRepository 的语义方法(如 getGoodsPage),无需关注 Retrofit/OkHttp 等实现细节。

如何扩展

  1. 新增 DataSource(可选):在 core/networkcore/databasecore/datastore 下实现数据源,并暴露注入入口。
  2. 创建 Repository:在 core/data/repository 中新增 XXXRepository 文件,引入需要的 DataSource,定义对外方法。
  3. 暴露方法:仓库返回 Flow/suspend 函数,必要时在内部合并多源数据。
  4. 注入使用:在 ViewModel 或 UseCase 中通过构造函数注入仓库,即可复用。

保持这一范式,数据来源的增加/替换将不会影响上层 Feature,实现“数据层可插拔、业务层稳定”的目标。