【问题标题】:Ways to create a layer of abstraction on top of a reactive database?在反应式数据库之上创建抽象层的方法?
【发布时间】:2019-10-14 18:07:15
【问题描述】:
我是响应式编程的新手,我似乎无法思考如何抽象一个响应式数据库,以便将来可以轻松地将它们换掉。
当前的目标数据库是 Realm,很容易在我的 DAO 类中简单地引用它们,它与我的存储库类进行通信。然而,经过一番思考,我可能应该在 DAO 之上创建一个抽象层,这样我就不会对 Realm 有硬依赖。在这种情况下,它或多或少会转发 Realm 的输入和输出。但是,我可以看到我可以在哪里尝试使标准 sqlite 数据库响应。
但在我走这条路之前,我想知道有没有这方面经验的人有更好的选择。
【问题讨论】:
标签:
android
realm
rx-java
reactive-programming
【解决方案1】:
而且我似乎不知道如何抽象出反应式数据库,以便将来可以轻松地将它们换掉。
您需要一个表示多个事件发射的最新值的通用抽象。
潜在的候选人是io.reactivex.Observable<T> 或LiveData<T>。
当前的目标数据库是 Realm,很容易在我的 DAO 类中简单地引用它们,它与我的存储库类进行通信。
直到您意识到 Realm 实例是线程本地的并且是引用计数的,这很诱人,因此如果您这样做,您将无法知道何时关闭领域(除非您将 Realm 传递给您的每个 dao.find*( 方法,或手动创建一个 ThreadLocal<Realm>,以便您可以跟踪何时关闭它。)
在这种情况下,它或多或少会转发 Realm 的输入和输出。但是,我可以看到我可以在哪里尝试使 标准 sqlite 数据库具有响应性。
虽然 Room 和 SqlDelight 对此提供了支持,但您可以在 this repo of mine 中查看如何自己创建一个简单的 SQLite 包装器。
但在我走这条路之前,我想知道有没有这方面经验的人有更好的选择。
如果您想让 Realm“独立于 Realm”并且可以在不依赖其惰性求值的情况下进行观察,您可以将 Realm 放在后台循环线程 (HandlerThread) 上,当您使用该线程映射项目时检测变化。
这个后台循环线程上的这些 RealmResults 必须保存在一个 Set 中,以保持对它们的强引用,以便保持监听变化的能力。
如果您停止观察您打开的所有 RealmResults,那么您可能希望自动关闭 Realm。
虽然我不再真正接触该项目,但您可以查看 Realm-Monarchy(由我编写),它与我上面提到的完全一样:将 RealmResults 包装到 LiveData<List<T>> 中,以便可以与其他任何东西交换(包括例如Room)。如果您愿意,可以涉足其源代码。