Search code examples
androidkotlinmappingkotlin-extension

Mapping model classes with Kotlin


I'm looking a way to improve the mapping mechanisms between the model classes from the different layers in my App.

I've model classes, the ones that I use in my App, in the business logic layer such as a Presenter. For example a User class.

I've server-side entities, these are the ones that I use to deserialize the responses from the server-side endpoints, through Retrofit or any other technology. These ones usually contain the Gson annotations for the fields. For example a ApiUserResponse class.

And I've DTO entities, these are the ones that represent a DB table in my App. I'm using Realm right now, but I've worked with ORMlite and Room. These types of classes also contain DB related annotations. For example a UserDTO class.

My cache repositories (the ones that fetch data from the DB) and my network repositories (the ones that fetch data from the server-side) both expose RxJava methods, returning the responses wrapped in Observable classes.

What I'm doing right now to parse the DTO entities and the server-side entities is add an extended function to the Observable class which receives a functions as argument. And that's the mechanism that I'm using to parse the DTOs and server-side entities into model classes. For example:

myLoginRepository.getUser("someId")
    .mapTo(::myMappingFunction)

...

fun myMappingFunction(userResponse: ApiUserResponse): User {
    return User(userResponse.id, userResponse.name, userResponse.lastname)
}

Internally the only thing that the mapTo extended function does is using a flatMap to flat the Observable stream and using a map to parse the collection.

I think that this is a pretty good way to implement the mapping between model-related classes, but I'm looking a way to improve it or do something completely different but that require less coding. Obviously this example is pretty straight forward, but currently I'm having a Mappings.kt file which is growing like crazy with each new mapping function.

Any suggestion?


Solution

  • Maybe http://modelmapper.org/ is something for you. This way you can spare your own mapping functions and you can even specify some sophisticated mapping functions. However it may cost you something in regards to performance (looks like reflection access all the way?).

    Note: I didn't use the library myself yet, but it looks promising enough to recommend it. In the last project I helped out, they built their own modelmapper which probably wasn't such a good idea (lots of corner cases forgotten, which then led to strange behaviour later on or manually mapped the wrong fields; however your variant can suffer from that too).

    Just found another article regarding mapping frameworks and their performance: http://www.baeldung.com/java-performance-mapping-frameworks doesn't look that good for ModelMapper

    You may also just want to generate your mapping functions. Similar to what you have now. Or just use a live template for it?

    Manually writing your mappings may sooner or later introduce mistakes you are not identifying that easily anymore, except you test them all accordingly. Which you do, right? ;-)