【发布时间】:2018-02-17 09:59:30
【问题描述】:
最近,我了解到在设计应用程序的后端(存储库,而不是服务器端后端)时,拥有单一真相 (SSOT) 是多么重要。 https://developer.android.com/topic/libraries/architecture/guide.html
通过开发一个新闻提要应用程序(使用了不起的https://newsapi.org/),我试图了解有关应用程序架构的更多信息。 但是,我不确定如何为我的应用程序设计存储库界面。 顺便说一句:我正在使用 MVVM 作为我的表示层。 View 订阅 ViewModel 的 LiveData。 ViewModel 订阅 RxJava 流。
所以我想出了两种方法:
方法一:
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 中加载,......),就会发出数据。但是,我不确定为 SearchArticleRepository#searchArticles(...) 使用 Flowable 是否有意义。因为它就像一些请求/响应的事情,也许 Single 可能会让我更直观。
方法二:
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)。
最后,我想知道采用哪种方法以及为什么。 有最佳实践吗?我知道你们中的许多人已经完成了一些更大的软件项目/应用程序,如果你们中的一些人可以与我和其他人分享一些知识,那就太棒了。
非常感谢!
【问题讨论】: