Me and my colleague are having a debate as to where would be the right place to map our entity objects or remote dto objects to plain simple domain objects.
Our structure looks like this.
source(includes dao) > repo(includes source) > usecase(includes repo)
My colleague thinks that mapping to domain should be done inside the source so that the domain object could be passed on to the next layers as so
class SomeSourceImpl(private val dao: Dao) : SomeSource {
override fun get(): Observable<DomainModel> {
return dao.getResponse().map { it.mapToDomain() }
}
}
My colleagues argues that according to Uncle Bob this is due to the dependency rule.
This rule says that source code dependencies can only point inwards. Nothing in an inner circle can know anything at all about something in an outer circle. In particular, the name of something declared in an outer circle must not be mentioned by the code in the an inner circle. That includes, functions, classes. variables, or any other named software entity.
I very much disagree with the approach of mapping to domain directly inside the source because then the repositories become anaemic and we are consequently adopting the anti-pattern of anaemic repositories being useless and all they do is to blindly propagating everything that comes from the source. (Now you may say that sources are also anaemic and we could simply remove them and include the dao object directly into the repo but this is out of the question in our case).
Instead I propose that sources would return the raw database entity (or remote entity if we are into rest calls) as it makes sense for a source to return the raw data for later processing. It's the job of the repo to get the result from the source then map it to domain and lastly propagate this domain object to use cases something like so.
class SomeRepoImpl(private val someSource: SomeSource) : SomeRepo {
override fun get(haId: String): Observable<DomainModel> {
return otherAssetSource.get().map { it.mapToDomain() }
}
I also came across some samples on github where they map to domain inside their repos rather than the sources
Here is one for iOS too
What would be the strict rule in clean architecture principles regarding the place one can map an entity into a domain object?