最近,我读到了在设计应用程序的后端(存储库,而不是服务器端后端)时拥有真实的单一来源(SSOT)的重要性。 https://developer.android.com/topic/libraries/architecture/guide.html
通过开发新闻源应用程序(使用很棒的https://newsapi.org/),我试图了解有关应用程序体系结构的更多信息。
但是,我不确定如何为我的应用程序设计存储库接口(interface)。
顺便说一句:我正在将MVVM用于我的表示层。 View 订阅了ViewModel的LiveData。 ViewModel订阅RxJava流。
所以我想出了两种方法:
方法1:
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
}
这种方法主要是使用Flowables,如果底层SSOT(数据库)中的相应数据发生更改(例如,旧数据已被API中的新数据替换,API中已加载的更多数据等),则Flowable会发出数据。但是,我不确定对
SearchArticleRepository#searchArticles(...)
使用Flowable是否有意义。就像一些请求/响应一样,也许“单例”可能更直观。方法2:
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.
}
这种方法使用Singles而不是Flowables。这看起来非常直观,但是如果SSOT中的数据发生更改,则不会发出任何更改。相反,必须再次调用存储库。要考虑的另一方面是ViewModel可能必须管理自己的状态。
让我们以
FeedViewModel
为例(伪代码)。class FeedViewModel : ViewModel() {
// Variables, Boilerplate, ...
val newsFeed: LiveData<List<Article>>
private val articles = mutableListOf<Article>()
fun loadNewsFeed() {
// ...
repository.loadFeed()
//...
// On success, clear the feed and append the loaded articles.
.subscribe({articles.clear(); articles.addAll(it)})
// ...
}
fun loadMore() {
// ...
repository.loadMore()
//...
// On success, append the newly loaded articles to the feed.
.subscribe({articles.addAll(it)})
// ...
}
}
因此,这对于像我这样的小型应用程序可能并不重要,但对于大型应用程序肯定会遇到问题(请参见状态管理:http://hannesdorfmann.com/android/arch-components-purist)。
最后,我想知道采用哪种方法以及为什么。 有最佳做法吗? 我知道你们中许多人已经做过一些较大的软件项目/应用程序,如果你们中的一些人可以与我和其他人分享一些知识,那真是太棒了。
非常感谢!
最佳答案
在您的情况下,我宁愿使用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
的建议。另一方面,与问题本身无关,我对
loadMore
或moreArticles
方法的用途有严重怀疑,因为它们返回Completable
。在不知道上下文的情况下,似乎您可以通过更好的名称来重构方法名称,或者如果它们按照名称执行了似乎要执行的操作,则可以更改返回类型。关于android - Android资源库模式和RxJava:使用Flowable还是Single?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48840087/