1

我正在将我的应用程序转换为房间数据库,并尝试遵循基于“带视图的房间”的谷歌架构最佳实践。

我无法从干净架构的角度理解存储库。

Words 数据库示例仅包含一个表和一个使用它的视图,使其成为一个简单的 HelloWorld 示例。但让我们从那开始。

有一个显示单词列表的视图。因此,所有单词都需要从数据库中读取并显示。所以我们有一个 MainActivity 和一个要连接的数据库。

  1. 实体词
  2. WordDao 访问数据库
  3. WordViewModel:为了将活动生命周期与数据生命周期分开,使用了 ViewModel。
  4. WordRepository:因为数据可能保存在数据库或云中或任何引入存储库以处理数据来自何处的决策。
  5. 活动与视图

如果在数据更改时更新视图会很好,因此使用 LiveData。

这反过来意味着,存储库正在为完整表提供 LiveData:

// LiveData gives us updated words when they change.
val allWords: LiveData<List<Word>>

对于单一视图来说,这一切都很好。

现在来回答我关于扩展这个概念的问题。

让我们假设,单词表有两列“word”和“last_updated”作为时间字符串。

为了更容易比较时间字符串需要转换为毫秒,所以我有一个函数。

问题:在哪里放置有趣的 queryMaxServerDateMS() 以获得最大值(last_updated)?

/**
 * @return Highest server date in table in milliseconds or 1 on empty/error.
 */
fun queryMaxServerDateMS(): Long {
    val maxDateTime = wordDao.queryMaxServerDate()

    var timeMS: Long = 0
    if (maxDateTime != null) {
        timeMS = parseDateToMillisOrZero_UTC(maxDateTime)
    }
    return if (timeMS <= 0) 1 else timeMS
}

对我来说,将它放入 WordRepository 是很自然的。

第二个要求:后台作业更新数据库中的单词列表。

假设我现在想要一个定期安排的后台作业,它检查服务器是否有新条目并将它们下载到数据库。该应用程序可能未打开。

这个问题只是转达了上面queryMaxServerDateMS的问题。

该作业将首先检查是否通过询问服务器是否存在比最大已知条目更新的条目来创建新条目。

所以我需要获取一个新类 WordRepository,进行查询,获取 max last_update 并询问服务器。

但是:我不需要后台作业中的 LiveData,当 val repositoy = WordRepository 读取完整的表时,这是不必要的,而且会耗费时间、内存和电池。

我还可以想到许多不同的片段,它们需要单词表的一些数据,但从不需要完整数据,想想列出一个产品的产品详细信息屏幕。

所以我可以将它移到另一个存储库或 DbHelper 中,但是你想调用它。

但最后我想知道,如果我使用 LiveData,它需要 View、ViewModel 和 Repository 紧密耦合在一起:

问题:我是否需要为每个活动/片段创建一个存储库,而不是为每个表创建一个更符合逻辑的存储库?

4

2 回答 2

1
  1. 是的,使用您当前的架构,您应该将其放在Repository.
  2. 不,您不需要每个活动/片段的存储库。最好为 1 个实体创建 1 个存储库。你可以有一个UseCasefor each ViewModel

在 Clean 架构中有一个 UseCase / Interactor 的概念,它可以包含业务逻辑,而在 Android 中它可以充当 and 之间的附加层ViewModelRepository您可以为您的函数创建一些 UseCase 类queryMaxServerDateMS(),将其放在那里并从任何ViewModel您需要的地方调用它.

您也可以LiveData通过调用同步获取您的价值getValue()

于 2019-11-20T12:39:53.050 回答
0

您不需要每个活动或片段的存储库。要回答有关获得最大服务器时间的问题 - 当您从 db 加载单词时,您几乎可以访问整个表。这意味着您可以自己进行计算以确定添加的最新单词,或者您可以通过在 dao 中添加另一个查询并在您的存储库中访问它来将该工作委托给房间。为了简单起见,我更喜欢后者。

要回答您有关在不同活动或片段中使用 repo 的问题 - room 缓存您的计算,以便它们可用于您的 repo 的不同用户(最终是 dao)。这意味着如果您已经计算了一个活动中的最大服务器时间并在那里使用它,那么其他生命周期所有者可以使用该计算结果,只要表没有被更改(可能还有其他条件)

总而言之,您对拥有表而不是活动或片段的存储库是正确的

于 2019-11-21T05:51:17.743 回答