Android存储库模式& RxJava:使用Flowable还是Single?

时间:2018-02-17 09:59:30

标签: android kotlin rx-java2

最近,我读到了在设计应用程序的后端(存储库,而不是服务器端后端)时拥有单一来源(SSOT)的重要性。 https://developer.android.com/topic/libraries/architecture/guide.html

通过开发新闻Feed应用程序(使用真棒https://newsapi.org/),我试图了解有关应用程序架构的更多信息。 但是,我不确定如何为我的应用程序设计存储库界面。 顺便说一句:我正在使用MVVM作为我的表示层。 View订阅了ViewModel的LiveData。 ViewModel订阅了RxJava流。

所以我想出了两种方法:

方法1:

sed -r '/70-Error/h;//!H;$!d;x;s/((\n[^\n]*){3}).*/\1/' file

这种方法主要使用Flowables,如果底层SSOT(数据库)中的相应数据发生变化(例如旧数据被API中的新数据替换,更多数据从API加载,......),它会发出数据。但是,我不确定使用Flowable for interface NewsFeedRepository { fun loadFeed(): Flowable<List<Article>> fun refreshFeed(): Completable fun loadMore(): Completable } interface SearchArticleRepository { fun searchArticles(sources: List<NewsSource>? = null, query: String? = null): Flowable<List<Article>> fun moreArticles(): Completable } interface BookmarkRepository { fun getBookmarkedArticles(): Flowable<List<Article>> fun bookmarkArticle(id: String): Completable } 是否有意义。因为它就像一些请求/响应的东西,也许Single可能更直观。

方法2:

SearchArticleRepository#searchArticles(...)

这种方法使用的是Singles而不是Flowables。这似乎非常直观,但如果SSOT中的数据发生变化,则不会发生任何变化。相反,必须再次调用存储库。另一个需要考虑的方面是ViewModel可能必须管理自己的状态。 我们以interface NewsFeedRepository { fun loadFeed(): Single<List<Article>> fun refreshFeed(): Single<List<Article>> fun loadMore(): Single<List<Article>> } interface SearchArticleRepository { fun searchArticles(sources: List<NewsSource>? = null, query: String? = null): Single<List<Article>> fun moreArticles(): Single<List<Article>>​ } interface BookmarkRepository { fun getBookmarkedArticles(): Single<List<Article>> fun bookmarkArticle(id: String): Single<Article> // Returns the article that was modified. Articles are immutable. ​ } 为例(伪代码)。

FeedViewModel

所以这对于像我这样的小应用程序来说可能并不重要,但对于更大的应用程序来说肯定会遇到问题(请参阅状态管理:http://hannesdorfmann.com/android/arch-components-purist)。

最后,我想了解采取哪种方法以及原因。 有没有最好的做法?我知道你们很多人已经做过一些较大的软件项目/应用程序,如果你们中的一些人可以与我和其他人分享一些知识,那真的很棒。

非常感谢!

2 个答案:

答案 0 :(得分:1)

我相信第一种方法更好,只要数据发生变化,您的仓库就会更新数据,并且您的视图模型会自动通知并且很酷,而在您的第二种方法中,您必须再次调用仓库并且这不是真的反应式编程。

此外,假设数据可以通过某些内容进行更改,而不是从视图中加载更多事件,例如添加到服务器的新数据或应用程序的某些其他部分更改数据时,现在再次在第一种方法中获取数据自动,而第二个你甚至不知道更改的数据,你不知道何时再次调用该方法。

答案 1 :(得分:1)

我宁愿在你的情况下使用Observable而不是Flowable来采用第一种方法:

interface NewsFeedRepository {
    fun loadFeed(): Observable<List<Article>>
    fun refreshFeed(): Completable
    fun loadMore(): Completable
}

interface SearchArticleRepository {
    fun searchArticles(sources: List<NewsSource>? = null, query: String? = null): Observable<List<Article>>
    fun moreArticles(): Completable
}

interface BookmarkRepository {
    fun getBookmarkedArticles(): Observable<List<Article>>
    fun bookmarkArticle(id: String): Completable
}

我认为您没有必要为此目的使用Flowable,因为您永远不会有任何与OOME相关的问题来检查您的存储库更改。换句话说,对于您的用例,根本不需要IMHO背压。

检查this official guide,它会向我们提供有关何时Flowable超过Observable的建议。

另一方面,与问题本身无关,我严重怀疑loadMoremoreArticles方法的目的是什么,因为它们返回Completable。在不知道上下文的情况下,您可能看起来可以通过更好的名称重构方法名称,或者如果它们按照名称执行它们的操作,则更改返回类型。