在开发 Android 应用程序并尝试遵循干净的架构指南时,最好的方法是什么(但不是非常严格——因为这对于小型项目来说可能是矫枉过正)。
就我而言,我不确定哪种方法对于 数据层是最好的(如果有最好的),以及数据层是否应该在其自己的模型类上运行,或者它是否可以直接在域层模型上运行。
此外,如果数据层应该在其自己的模型类上运行,数据源是否应该喜欢DB
或API
拥有自己的模型(例如API
使用Retrofit
和Gson
带有Gson
注释的模型类),然后映射到数据层模型,或者数据层模型本身应该是DB
and返回的模型API
(这意味着必须对数据层模型进行注释,以便在andGson
的情况下能够解析它)。Retrofit
Gson
以下图片应阐明我的意思的 3 种方法:
在图 1中DB
,API
返回特定的模型类。在的情况下,API
它可能看起来像(使用Retrofit
and Gson
):
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 urlToImage: String?,
@SerializedName("publishedAt") val publishedAt: String?)
然后这些由本地/远程数据源映射到Article
模型(由域层使用)。因此,存储库在域层模型上运行并且打破了界限,对吗?那是方法1。
在图 2中DB
,API
仍然返回特定的模型类。在的情况下,API
它可能看起来像(使用Retrofit
and Gson
):
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 urlToImage: String?,
@SerializedName("publishedAt") val publishedAt: String?)
但是,这些模型随后会映射到数据ArticleEntity
层操作的数据层模型 ( )。当响应领域层时,repository
将这些映射ArticleEntity
到领域层模型Article
。这不会打破边界(右),但它需要在数据层中进行一些额外的映射。这是方法2。
在图 3中,DB
并且API
已经返回了数据层模型ArticleEntity
。因此,这个模型类必须包含解析 API 请求所需的所有注解(带有Gson
):
class ArticleEntity(@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 urlToImage: String?,
@SerializedName("publishedAt") val publishedAt: String?)
如果数据库还需要某种注释,那么这些注释也必须添加到此类中(对吗?)。我能想到的这种方法的一个优点是模型类更少(因为 DB 和 API 直接映射到数据层模型)。但是,这不会用来自所有不同数据源(DB、API)的注释/属性来破坏数据层模型类吗?是否违反了从存储库中抽象数据源的全部要点,因为数据层模型依赖于特定的数据源实现(例如,使用 Gson 解析具有确切 API 响应名称的 API 请求)。所以这是方法3。
我的问题是:这 3 种方法中哪一种是最灵活和面向未来的方法?