Ramir Junior
Ramir Junior28/11/2023 13:35
Compartilhe

Padrão de projeto Builder com exemplo em Java

  • #Java

Fala pessoal, tudo bem? Durante meus estudos e práticas resolvi compartilhar um assunto técnico voltado para o desenvolvimento dessa vez com Java. Bora lá?

Design Patterns são padrões de projeto frequentemente utilizados em desenvolvimento mobile e com esse conhecimento eu consegui identificar alguns deles na implementação de classe de bibliotecas que já usei em projetos!

Existem vários padrões no mundo de criação de software e cada tipo resolve um problema já conhecido e recorrente nos projetos. Cabe a nós, como desenvolvedores, analisar, aplicar e adaptar de acordo com a necessidade do projeto, por isso é sempre importante estar antenado sobre as possibilidades que melhor atendem à solução.

image

Hoje decidi compartilhar sobre o padrão de projeto Builder. Minha ideia era mostrar tanto em Java quanto em Kotlin, mas ficaria um pouco mais extenso o texto e decidi fazer somente com Java e em outra oportunidade trarei algo voltado para Kotlin.

Apresentando o problema

O Builder é um padrão de projeto que pertence aos tipos criacionais; esse tipo é focado em criar objetos complexos de maneira reutilizável, flexível e de fácil manutenção.

O problema é o seguinte, imagine que você gostaria de criar um hotel e precisaria informar a quantidade de andares, quartos, janelas e se haveria ou não estacionamento no subsolo (daqueles estilosos com luzes rs), possivelmente utilizaria uma instância da classe Hotel similar a essa:

image

Até aqui nada demais, são só 4 atributos a serem preenchidos, como sei a ordem dos atributos não preciso ficar indo lá na classe verificar, é simples criar um hotel assim:

image

Nesse caso eu posso contar com a ajuda do IntelliJ que me diz o que cada parâmetro significa para classe enquanto estou digitando. Fica fácil saber dentro da IDE, qual atributo estou preenchendo pra construir o hotel. Fim, está criado o hotel.

image

Temos alguns pontos pra considerar nesse momento:

  • E se eu acessasse o código usando outra IDE, eu veria os nomes dos atributos enquanto estou criando o objeto e saberia a ordem correta de cada um?
  • E se por acaso a classe Hotel precisasse de mais 2 ou 3 atributos pra criar hotéis com mais propriedades?
  • E se eu precisasse enviar meu código à um repositório remoto para que meu time conseguisse também criar hotéis, o repositório iria mostrar o que a classe precisa pra usá-la?

Bem, a partir daqui haveria uma série de diferentes cenários em que uma classe com vários atributos poderia nos tomar um tempo precioso procurando a ordem correta dos parâmetros, o que cada um deles significa e os valores coerentes pra cada um dos campos na hora de criar um hotel.

Aplicando o padrão Builder

Vamos ver o que é possível fazer utilizando o padrão Builder pra criar objetos do tipo Hotel e veremos no que ele nos ajuda. Agora vem a parte divertida, ihuu!

image

Primeiramente vou deixar o construtor da classe Hotel privado e agora quem quiser criar um hotel vai ser obrigado a usar a classe interna HotelBuilder que estou criando para isso. Então toda a responsabilidade de saber como criar hotel publicamente vai ser dessa classe que está dentro da classe Hotel dessa forma aqui:

image

Agora a classe interna HotelBuilder vai ter seus próprios atributos e métodos para acessar e preencher cada um deles. Mais à frente nós iremos mandar estes mesmos atributos (preenchidos ou não) para a classe externa Hotel e assim teremos nosso objeto montado.

Nesse momento, eu quero criar métodos que irão acessar os atributos da classe HotelBuilder e colocar os valores recebidos por parâmetro nos atributos desejados. Note que esses métodos sempre retornarão um objeto HotelBuilder. O divertido é que posso nomear os métodos de acordo com as propriedades que eles acessam. Assim:

image

E agora a cereja do bolo ou o ingrediente secreto ou O Grand Finale, enfim o método responsável por realmente mandar toda a informação para a classe externa Hotel é o método build. Ele vai pegar toda informação que foi coletada nos métodos que criei, irá acessar o construtor da classe externa Hotel e... Buumm! Irá retornar o objeto hotel criado com o construtor da classe externa utilizando todas as propriedades recebidas nos métodos.

image

Importante ressaltar que o retorno desse método sempre é do tipo de objeto que queremos obter no final, ou seja, o build deve retornar um Hotel.

Pra auxiliar na compreensão, eu criei um diagrama que ilustra um pouco do que acontece quando chamamos o método build que pertence a classe HotelBuilder.

image

E finalmente vamos ver essa belezinha de classe interna em ação criando um objeto Hotel.

image

Quando eu quiser criar um hotel, chamo a classe HotelBuilder dentro da classe Hotel. Em seguida posso chamar o método andares ou qualquer outro e só pelo nome do método já posso deduzir exatamente o que ele recebe e o que faz.

Considerações

Posso personalizar a classe HotelBuilder de acordo com minha necessidade. Por exemplo, eu poderia usar essa classe pra criar objetos Hotel com estacionamento já incluso, setando true para o atributo estacionamento internamente.

Usar o padrão Builder, remove a obrigação de declararmos todos os atributos da classe desejada, só não podemos esquecer de chamar o método build assim que já decidimos como será o objeto como no exemplo abaixo:

image

Nesse caso, sobre o hotel criado podemos dizer que os demais métodos que não foram usados aqui estão com valor 0 por padrão.

Podemos apontar algumas vantagens do padrão Build para criação de objetos:

  • A instanciação de objetos com o Build torna mais intuitivo o código. Com apenas um vislumbre do código, você consegue facilmente deduzir a maioria de seus atributos sem visitar a classe Hotel para saber como funciona.
  • A criação personalizada do objeto também nos permite iniciar atributos específicos daquela classe sem que seja obrigado declarar as demais propriedades do objeto;
  • Independente da quantidade de atributos que temos que preencher, posso chamá-los em qualquer ordem caso decida inserir um valor;
  • Temos ainda a possibilidade de criar nossos objetos utilizando funções com métodos mais robustos e mais práticos de serem modificados dentro da classe do Builder.

Bom gente, esse foi meu primeiro artigo e espero que tenham tido uma boa experiência e principalmente que tenham entendido o que tentei repassar da forma mais direta possível que pude. Não sou expert ainda, mas se tiver dúvida sobre o assunto coloca aqui que respondo.

Obrigado pelo seu tempo de leitura. Até a próxima, valeu!

image

Meu post original do linkedin

---------------

Aqui algumas referências que me ajudaram na concepção e recomendo :

---------------

Ramir Junior: aluno de Sistemas de Informação na PUC Minas / São Gabriel, atua como desenvolvedor Java / Kotlin desde 2021. Apaixonado por música, jogos, filmes de ficção e viagens.

Meu Linkedin | Meu Github | Instagram: @junior_ribeiro

Compartilhe
Comentários (2)
Marcio Herrero
Marcio Herrero - 28/11/2023 22:37

Ai sim, bem explicado e desenhado esse padrão Builder.

Parabéns pelo conteúdo!

Valeu!

Alisson Fabro
Alisson Fabro - 28/11/2023 15:45

Muito boa sua abordagem, parabéns Ramir!