Android アプリを開発し、クリーンなアーキテクチャのガイドラインに従おうとするときの最善のアプローチは何ですか (ただし、それほど厳密ではありません。小規模なプロジェクトではやり過ぎになる可能性があります)。
私の場合、データ層に関して どのアプローチが最適であるか (最善のアプローチがある場合) 、データ層が独自のモデル クラスで動作する必要があるのか、それともドメイン層モデルで直接動作する可能性があるのかがわかりません。
また、データレイヤーが独自のモデルクラスで動作する必要がある場合、データソースは独自のモデルを好むDB
かAPI
、独自のモデルを持っている必要があります(注釈付きのAPI
使用Retrofit
およびGson
モデルクラスの場合など)。データレイヤーモデルにマップするか、データレイヤーモデル自体をおよびによって返されるモデル(これは、およびの場合に解析できるように、データ層モデルに注釈を付ける必要があることを意味します)。Gson
DB
API
Gson
Retrofit
Gson
これは、このプロジェクトの場合です 。
次の画像は、私が意味する 3 つのアプローチを明確にする必要があります。
イメージ 1では、DB
とAPI
が特定のモデル クラスを返します。の場合、次のAPI
ようになります (Retrofit
とを使用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
とを使用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
マップされます。これは境界を壊しませんが (右) 、 data-layer に追加のマッピングが必要です。これがアプローチ 2 です。ArticleEntity
Article
画像 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 に何らかのアノテーションも必要な場合は、これらもこのクラスに追加する必要があります (そうですか?)。私が考えることができるこのアプローチの利点は、モデル クラスが少ないことです (DB と API がデータ層モデルに直接マップされるため)。しかし、これはすべての異なるデータ ソース (DB、API) からの注釈/プロパティでデータ層モデル クラスを爆発させませんか? データ層モデルが特定のデータ ソースの実装に依存しているため (たとえば、Gson を使用して正確な API 応答名で API 要求を解析するなど)、リポジトリからデータ ソースを抽象化するという点全体が違反しているのではないでしょうか。これがアプローチ3でした。
私の質問は次のとおりです。3 つのアプローチのうち、最も柔軟で将来性のあるものはどれですか?