I'm trying to apply clean architecture on my android projects, but it is quite complex, now I'm stuck on this, according to Uncle Bob you should use a model for every layer (domain, data, presentation - in this case), so, typically we create a data class for the domain layer, let's say "Movie":
data class Movie(
private val id: Int = 0,
private val name: String = "",
private val imageUrl: String = ""
)
So, later in our presentation layer we should have a model to be able to retrieve data from the network, we'll name it MovieDto and it looks like this:
data class MovieDto(
@Json(name = "id")
private val id: Int = 0,
@Json(name = "name")
private val name: String = "",
@Json(name = "image_url")
private val imageUrl: String = ""
)
Then every time we fetch data using Retrofit we should be getting a MovieDto object in return, but our MovieRepository in our domain layer looks this way:
interface RepositoryMovies {
suspend fun getMovie(id: Int): Movie
}
With the previous code we already stablished a contract agreeing to always return a Movie object (remember that inner layers should not know anything about outter layers, so our repository doesn't even know a MovieDto class exists), in order to be able to return a Movie object the repository should use a mapper to convert/map the MovieDto object comming from Retrofit to a Movie object. To avoid all of that I used an interface as my domain model, let me show you:
interface IMovie {
val id: Int,
val name: String,
val imageUrl: String
}
The only thing we have to do next is to implement the IMovie interface on our MovieDto class:
data class MovieDto(
@Json(name = "id")
private val id: Int = 0,
@Json(name = "name")
private val name: String = "",
@Json(name = "image_url")
private val imageUrl: String = ""
) : IMovie
Now our repository should return a IMovie interface instead:
interface RepositoryMovies {
suspend fun getMovie(id: Int): IMovie
}
With no need of mappers but still forcing "domain rules" by implementing the IMovie interface. I ask you to point me in the right direction, maybe I'm not seeing that this approach is not as flexible or scalable as I tought, what approach would you use? please feel free to comment any pros and cons of each approach. Thank you for your time.