My approach is something like I have my entity class let's say:
data class User(
private val name: String,
private val age: Int
)
And I have a DTO:
data class UserDto(
val name: String,
val age: Int
)
And the mapper function is an extension function of User (inside my class file):
User.mapToDto(UserDto u) {
this.name = u.name
this.age = u.age
}
My doubt is if this approach it is the best, because my DTO doesn't have private modifiers thinking it is a val attribute (so it will not be changed). Or there is a best way to do this, respecting concepts like encapsulation and all that clean code other stuff.
I already tried to make a mapper (in another file) but does not work because my entity class has private access, so it makes necessary to do it inside my class User.
I have a take on this question. First, the common approach that I commonly use is to have an extension function that maps an entity to its DTO.The approach is
data class User(
private val name: String,
private val age: Int
)
data class UserDto(
val name: String,
val age: Int
)
fun User.mapToDto(): UserDto {
return UserDto(name, age)
}
This approach makes sure that our code is aligned with the immutability principle.But in your case you have a private properties in your data class and if I use my first approach then I violate the encapsualtion principle. So to resolve this issue we have a second approach that is
data class User(
private val name: String,
private val age: Int
) {
fun getName(): String = name
fun getAge(): Int = age
}
data class UserDto(
val name: String,
val age: Int
)
fun User.mapToDto(): UserDto {
return UserDto(getName(), getAge())
}
So now our second approach allows better control over the internal affairs on our codebase and alligining with encapsulation principal