My question is as the title states.
Room has the annotation @Entity
, and within Room, this is considered an Entity
.
But in Clean architecture, when using a Domain layer,
an Entity
is also used.
For example, entities used by Use Cases within the domain layer.
However, I think that what Room considers an Entity
is a DTO
or POJO
as of Clean architecture.
With that being said, when creating an app, what should I name my model in the presentation layer, domain layer, and in the data layer?
Domain Layer:
Domain layer
is the centre point of the clean architecture which doesn't only contains data models
but also usecases
and domain layer is something that should be language specifics, which means there should be no third party involve you've to keep it to language. The domain layer is something that you are going to manage throughout the whole app even in unit tests(most of the time).
Framework Layer:
When you say Entity
or DTO
which we use with Room or Retrofit and these frameworks that we use with third party libs., these should belong to framework layer
of the architecture. That means these entities and dtos are not directly targeting the usecases or domain models but how can we use them or connect them with domain model? this is where mappers comes into play you've to use mapper mechanism to map the data from one layer to another and not to violate CA rules.
Example:
Entity:
@Entity(tableName = "user_auth")
data class UserAuthEntity(
@PrimaryKey(autoGenerate = false)
@ColumnInfo(name = "pk")
val uid: String,
@ColumnInfo(name = "user_name")
val username: String,
@ColumnInfo(name = "email")
val email: String,
@ColumnInfo(name = "password")
val password: String,
)
Domain Model:
data class UserAuth(
val uid: String,
val username: String,
val email: String,
val password: String,
)
we are going to use kotlin extension functions to map them:
fun UserAuth.fromDomain(): UserAuthEntity{
return UserAuthEntity(
uid, username, email, password
)
}
fun UserAuthEntity.toDomain(): UserAuth{
return UserAuth(uid, username, email, password)
}
How to use it:
suspend fun getUser(): UserAuth {
// this userAuth is from dao which Entity
val userAuth = dao.getUserEntity()
// map them userAuth domain through mapper extension functions
return userAuth.toDomain()
}
fromDomain
means we getting data from domain and mapping to Entity and toDomain
we are getting data from entity and mapping to domain.
As a side note, as it is mentioned above we are going to use mapper to map data between the layers. Since clean architecture based on layer
that doesn't mean we always going to use mappers everywhere to separate the layers and communication between the layers, since this question was about data models we normally use mapper to map the data which is in it by not breaking the layers.
Please search about DIP(dependency inversion principle), how we can communicate between different layers through interfaces.