小编Eli*_*as 的帖子

清洁架构:为不同的数据源使用不同的模型类?

我目前正在开发一个新闻提要Android应用程序.我尝试按照干净的架构原则设计我的应用程序.

在数据层中,我使用存储库模式作为不同数据源的外观:来自API的远程数据(https://newsapi.org/),来自DB(Realm或SQLite)的本地数据以及一些-memory缓存.
在我的域层中,我定义了一些不可变的模型类(Article,NewsSource等),它们由域层和表示层使用(在我看来,表示层中不需要额外的模型类).

为远程数据源和本地数据源使用不同的模型类是否有意义?

例如,远程数据源使用Retrofit进行API调用,并且需要对模型进行注释以便由GSON进行解析.

data class RemoteArticleModel(
        @SerializedName("title") val title: String,
        @SerializedName("urlToImage") val urlToImage: String,
        @SerializedName("url") val url: String)
Run Code Online (Sandbox Code Playgroud)

本地数据源的模型也可能必须满足某些特定合同,例如Realm DB中的模型需要扩展RealmObject.

open class Dog : RealmObject() {
    var name: String? = null
    @LinkingObjects("dog")
    val owners: RealmResults<Person>? = null
}
Run Code Online (Sandbox Code Playgroud)

显然,我不希望我的域模型被任何特定于数据源的契约(注释,RealmObject继承等)"污染".所以我认为为不同的数据源使用不同的模型是有意义的,并且存储库处理它们之间的映射.

例如,我们希望从远程API获取所有文章,将它们存储在本地数据库中并将它们返回到域层.

流程就像: 远程数据源向新闻api发出http请求并检索一个列表RemoteArticleModel.存储库会将这些模型映射到特定于域的文章模型(Article).然后将这些映射到DB模型(例如RealmArticleModel)并插入到DB中.最后,列表Article将返回给调用者.

出现两个问题: 上面的例子显示了使用这种方法会有多少分配.对于要下载并插入数据库的每篇文章,将在该过程中创建三个模型.那会有点矫枉过正吗?

另外,我知道数据层应该使用与域层不同的模型类(内层应该没有关于外层的任何内容).但是在上面的例子中,这有什么意义呢?我已经有两个不同的模型类用于两个不同的数据源.添加第三个被数据层/存储库用作"中介"模型以处理到其他模型(远程,本地,域)的映射将添加更多的分配.

那么,数据层是否应该对域模型一无所知,让域从数据层模型到域层模型进行映射?

应该只有存储库/数据层使用的通用模型吗?

谢谢,非常感谢更有经验的开发人员的帮助:)

android repository-pattern kotlin clean-architecture

8
推荐指数
1
解决办法
1495
查看次数

Android 应用程序干净架构:数据层是否应该有自己的模型类?

在开发 Android 应用程序并尝试遵循干净的架构指南时,最好的方法是什么(但不是非常严格 - 因为这对于较小的项目来说可能是矫枉过正的)。

就我而言,我不确定哪种方法是最好的(如果有最好的)关于 数据层,以及数据层是否应该在自己的模型类上运行,或者它是否可以直接在域层模型上运行。

此外,如果数据层应该在自己的模型类上运行,数据源是否应该像DBAPI拥有自己的模型(例如用于API使用RetrofitGson带有Gson注释的模型类),然后映射到数据层模型,或者数据层模型本身应该是DBand返回的模型API(这意味着必须对数据层模型进行注释,以便Gson能够在Retrofitand 的情况下解析它Gson)。

这个项目就是这种情况: https : //github.com/android10/Android-CleanArchitecture/blob/master/data/src/main/java/com/fernandocejas/android10/sample/data/entity/UserEntity.java

下面的图片应该阐明我的意思的 3 种方法:

图 1 中DBAPI返回特定的模型类。在它的情况下,API它可能看起来像(使用RetrofitGson):

class ArticleResponse(@SerializedName("source") val source: SourceResponse,
                          @SerializedName("author") val author: String?,
                          @SerializedName("title") val title: String,
                          @SerializedName("description") val description: String?,
                          @SerializedName("url") val url: String,
                          @SerializedName("urlToImage") val …
Run Code Online (Sandbox Code Playgroud)

android data-layer kotlin clean-architecture

6
推荐指数
1
解决办法
1895
查看次数

Android:存储库模式和分页

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

通过开发新闻提要应用程序(使用awesome https://newsapi.org/),我试图了解有关应用程序架构的更多信息.但是,我不确定如何实现分页.顺便说一下,.:我正在使用MVVM作为我的表示层.View订阅了ViewModel的LiveData.ViewModel订阅了RxJava流.

我提出了以下方法:

interface NewsFeedRepository {
        fun getNewsFeed(): Observable<List<Article>>
        fun refreshFeed(): Completable
        fun loadMore(): Completable
}
Run Code Online (Sandbox Code Playgroud)

ViewModel订阅getNewsFeed()Observable,它在每次数据库中的基础数据(SSOT)发生更改时发出数据.但是,我的问题是关于这个loadMore()方法.此方法尝试从API加载更多文章,并在成功时将它们插入本地数据库.这会导致getNewsFeed()发出新的Feed数据.

我的问题:

1.存储库是否应负责同步API和本地数据库数据?或者存储库是否应该使用一些管理同步网络/本地数据的"低级"API?

2.该方法loadMore返回一个Completable看似奇怪/误导的方法.是否有更好的方法在存储库界面中指示分页?

3.分页意味着存储当前页数并在从API请求数据时使用它.应该在哪里存储当前页数?在存储库中?或者在存储库使用的某些"低级"组件中?

interface SearchArticleRepository {
    fun searchArticles(sources: List<NewsSource>? = null, query: String? = null): Flowable<List<Article>>
    fun moreArticles(): Completable  
}
Run Code Online (Sandbox Code Playgroud)

此存储库用于搜索文章.该方法moreArticles()尝试根据最后一次调用从API加载更多文章searchArticles(...).例如:ViewModel调用repo.searchArticles(q = "bitcoin").调用repo.moreArticles()尝试"bitcoin"从API 加载包含查询字符串的更多文章并与本地数据库同步.

我的问题再一次:

1.是否可以存储有关上一个请求的信息(searchArticles(request)在存储库中?我也可以考虑传递请求参数moreArticles(),例如moreArticles(sources: List<NewsSource>? = null, query: …

android kotlin rx-java2

6
推荐指数
0
解决办法
930
查看次数