Murilo Eduardo
Murilo Eduardo Crossfiteiro, entusiastas de tecnologias e amante de novas tendências de softwares. Não dispenso uma cervejinha e um bom livro.

Map Struct - Criando objetos DTOs de forma mais elegante

Map Struct - Criando objetos DTOs de forma mais elegante

Neste artigo será apresentado a biblioteca Map Struct que permite criar objetos dtos e serializa-los de forma mais elegante, simples e prática.

Data Transfer Object, comumente conhecido como DTO é um padrão de projetos muito utilizado em várias linguagens de programação. É destinado para o transporte de dados entre diferentes camadas do sistema. A proposta é possuir uma classe mais simples e leve para melhorar a comunicação e otimizar o processamento.

Sobre sua aplicabilidade

O padrão DTO, resolver vários problemas, um deles é onde possuirmos o cadastro de uma entidade, mas algumas informações não necessariamente são obrigatórias ou necessárias, nesse caso, podemos criar uma classe secundária onde tenha os campos necessários e depois realizarmos a conversão/mapeamento para a entidade. Se procurarmos algum exemplo especificamente com Java, nos deparamos com os seguintes exemplos. Onde existe uma classe DTO e dentro dela, temos um construtor fazendo o de-para.

Exemplo prático

Para este exemplo, vamos imaginar que o nosso sistema é composto por uma tela de um sistema de cadastro de usuários, no módulo de cadastro de usuário, certos campos não são obrigatórios no envio da requisição. A classe abaixo representa a entidade User.

Contudo, o sistema não necessita que no momento de criação seja informado o id do cliente e se o usuário está ativo ou não, para isso criamos um DTO, um objeto mais simples para representar o nosso cadastro. A classe abaixo representa o nosso UserDTO.

Bom, na teoria, o nosso DTO está funcional e atendendo a necessidade de cadastro de usuários, mas em uma ensolarada manhã, a necessidade do cliente muda e o Product Owner chega na sua mesa informando que nesta tela, onde temos o cadastro de usuário torna-se necessário informar mais informações do cliente, como número do pedido, cidade e estado.

Agora temos um cenário onde toda e qualquer alteração precisa incrementar o nosso construtor UserDTO convertToUser(User user). Nesse cenário, temos seis propriedades, até aí tudo bem. Mas se considerarmos, a tendência do software de ir mudando a necessidade da tela de cadastro de usuário ficará muito inviável manter esse construtor, pois ele não irá parar de crescer ferido o princípio SOLID Open-closed principle, onde define que uma entidade deverá estar aberta para extensão, mas fechada para modificação.

Nessa parte que entra a lib MapStruct, a proposta dela é simplificar a implementação de mapeamento entre tipos. É rápido, seguro e fácil de implementar e entender. A utilização e serialização de DTO/Entidades é simplificada com o uso dessa dependência.

Para iniciar a implementação, é necessário importa-la ao projeto na documentação oficial é demostrado essa inclusão;

1
2
3
4
5
6
7
dependencies {
    ...
    implementation 'org.mapstruct:mapstruct:1.4.2.Final'
 
    annotationProcessor 'org.mapstruct:mapstruct-processor:1.4.2.Final'
}

Uma abordagem que particularmente eu curto é a utilização de static factory method juntamente com uma classe abstract, onde a conversão ficaria da seguinte forma;

Assim a nossa classe de serviço terá uma única instância do Mapper e a leitura fica bem mais agradável;

Essa implementação pode ser utilizada em várias camadas e tornará esse tipo de conversão muito fácil.

Encerramento

Foi apresentado a utilização do MapStruct para mapeamento de DTOs com o uso de static factory method. Com essa abordagem, se surgir a necessidade de aumentar as propriedades da nossa tela de cadastro basta incluir as propriedades nas classes User e UserDTO. O construtor que poderia se tornar um godzilla já não existe nessa cenário. Ficando mais limpa e prática.

Na sequência, abordaremos um comparativo entre MapStruct e a biblioteca ModelMapper.

Código fonte

O código fonte está disponibilizado aqui.

comments powered by Disqus