В огромном приложении Android с Clean Architecture много рутинной работы, связанной с отображением объектов между различными слоями. Хорошим решением будет автоматизация этого процесса.
В этой статье рассматривается опыт использования библиотеки MapStruct, которая помогает mapp-ить объекты.
Библиотека очень гибка в настройке. И позволяет минимизировать написание шаблонного кода.
Вот пример того, как реализовать gradle зависимости в вашем проекте.
plugins { kotlin("kapt") version "1.9.22" } dependencies { implementation("org.mapstruct:mapstruct:1.6.0") kapt("org.mapstruct:mapstruct-processor:1.6.0") }
Нажмите Синхронизировать ваш проект и начнем с самого простого и элементарного примера. Допустим, у нас есть два объекта:
data class PersonResponse( val id: Long, val name: String, val birthday: String ) data class Person( val id: Long, val name: String, val birthday: String, )
Для создания mapper-a нам необходимо создать интерфейс:
@Mapper interface MapperPerson { fun userResponseToUser(userResponse: PersonResponse): Person companion object { val INSTANCE = Mappers.getMapper(MapperPerson::class.java) } }
Вот и все! Mapping уже работает.
@Test fun `test map PersonResponse to Person`() { val response = PersonResponse(1, "John", "2024.01.01") val person = MapperPerson.INSTANCE.personResponseToPerson(response) assert(person.name == "John") }
Mapping вложенного объекта
Давайте рассмотрим немного более сложный случай.
data class PersonResponse( val id: Long, val name: String, val birthday: String, val educationResponse: EducationResponse ) data class EducationResponse( val universityName: String ) data class Person( val id: Long, val name: String, val birthday: String, val education: Education ) data class Education( val universityName: String )
Поэтому нам нужно изменить mapper следующим образом:
@Mapper(uses = [MapperEducation::class]) interface MapperPerson { @Mapping(source = "userResponse.educationResponse", target = "education") fun personResponseToPerson(userResponse: PersonResponse): Person companion object { val INSTANCE = Mappers.getMapper(MapperPerson::class.java) } } @Mapper interface MapperEducation { fun map(educationResponse: EducationResponse) : Education }
И тест пройден.
@Test fun `test map PersonResponse to Person`() { val response = PersonResponse( id = 1, name = "John", birthday = "2024.01.01", educationResponse = EducationResponse("University") ) val person = MapperPerson.INSTANCE.personResponseToPerson(response) assert(person.name == "John") }
В статье рассмотрены базовые случаи mapping-a с использованием библиотеки MapStruct. Более сложные случаи будут рассмотрены в следующих статьях. Спасибо за внимание!
ссылка на оригинал статьи https://habr.com/ru/articles/839362/
Добавить комментарий