Por que eu devo ler este artigo: Com a utilização de padrões de projetos em nossos sistemas podemos obter um melhor rendimento em nossas aplicações, fazendo uso de reutilização de código, maior desacoplamento entre as classes, dentre outros pontos favoráveis que possamos imaginar. Com base nisso, podemos ter aplicações robustas e de alta qualidade, além de deixarmos um código mais organizado e entendível no caso de uma manutenção. No entanto, é necessário que saibamos como melhor aplicar um determinado padrão em nossa aplicação, mas isso só acontece se compreendermos todo o processo que envolve os padrões de projetos.

Em que situação esse tema é útil?: Este tema é útil para o que possamos entender como se dá a aplicação desses padrões para que possamos trabalhar no desenvolvimento de nossos sistemas, sempre buscando garantias de um código autêntico, simples e mais rápido. Com a correta aplicação dos padrões de projeto, em especial os padrões Builder, Prototype e Singleton, estaremos melhorando nossos projetos a níveis favoráveis de escalabilidade, baixo acoplamento, dentre outros pontos, o que facilitará em futuras manutenções e consequentemente novas implementações que serão solicitadas para a aplicação.

Os padrões de projetos, no seu começo, eram apenas conjuntos de blocos de códigos populares que muitas vezes eram compartilhados sem muita “importância” entre desenvolvedores e designers de aplicação. Neste momento de compartilhamento de conhecimentos, surgiram quatro dos mais importantes projetistas de software que se destacaram quando “pegaram” esses blocos de códigos e então definiram o termo que é conhecido hoje como “Design pattern”. Hoje, esses projetistas são conhecidos como GoF (Gang of Four ou Gangue dos quatro) que é composta por Erich Gamma, Richard Helm, Ralph Johson e John Vlissides.

Os padrões de projetos são uma poderosa ferramenta para os desenvolvedores de softwares atualmente. No entanto, esses padrões não devem ser vistos como especificações prescritas para um software. O mais importante é entendermos os conceitos que descrevem estes padrões de projetos, descrever a sua essência, ao invés de tentar memorizar suas classes, métodos e propriedades. É também de igual importância aplicar esses padrões de forma adequada, buscando a melhor opção para o problema que precisa ser solucionado. Usando os padrões de forma incorreta para uma determinada situação ou a aplicação de um padrão de projetos a uma solução trivial pode complicar ainda mais o código, o que nos levaria a problemas de manutenção. E é por isso, que estaremos abordando neste artigo, os três últimos padrões do grupo criacional que são os padrões Builder, Prototype e de certa forma, o mais conhecido dentre os padrões de projetos, o padrão Singleton.

Padrão de projetos Builder

O padrão de projetos conhecido como Builder faz parte do grupo de padrões titulado como padrões criacionais definidos pelo GoF, dos quais começamos a tratar no artigo anterior, onde trabalhamos com os padrões de fábrica, Abstract factory e Factory Method. O padrão builder, por outro lado, é utilizado para construção de objetos complexos fazendo-se uso de uma abordagem de desenvolvimento passo a passo.

Por que devemos utilizar o padrão de projetos Builder?

O padrão Builder é um padrão de projetos de software comum que é usado para encapsular a lógica de construção de um objeto. Este padrão é frequentemente utilizado quando o processo de construção de um objeto é considerado complexo e também é adequado quando se trata da construção de representações múltiplas de uma mesma classe.

Quanto mais complexa for uma aplicação, maiores serão as complexidades existentes nas classes e objetos criados. Objetos complexos passam a ser construídos a partir de peças geradas a partir de outros objetos, o que demanda uma necessidade maior em relação a sua construção, um cuidado especial poderíamos dizer. Desta forma, podemos dizer que uma aplicação poderá precisar de um mecanismo para a construção de objetos complexos, que será independente das que o compõem. Se este é o tipo de problema ao qual estamos nos deparando na nossa aplicação, que tal utilizarmos o padrão de projetos builder?

Este é o tipo de padrão que permite que um objeto cliente seja capaz de construir um objeto complexo, especificando apenas o seu tipo e o seu conteúdo, sendo então protegido dos detalhes relacionados com a representação do objeto, entrando aqui o conceito de encapsulamento. Desta forma, o processo de construção pode ser usado para a construção de diferentes representações. A lógica deste processo é isolar a forma que os passos reais usados na criação de objetos complexos tomam, de modo que o processo possa ser usado novamente para a criação de um conjunto de objetos simples de igual forma a criação do primeiro.

Quais são os participantes que constituem o padrão Builder?

O padrão em questão é composto por quatro componentes básicos que são a Interface (ou classe abstrata) Builder, o concrete builder (construtor concreto), o Director (Diretor) e o product (produto). Vejamos a seguir o que cada um deles é responsável em fazer:

  • Classe Builder – esta classe especifica uma interface ou uma classe abstrata para a criação das partes (ou podemos considerar como sendo os passos que serão realizados) de um objeto a fim de criar corretamente o produto (Product). Cada um desses passos são, geralmente, abstrações das funcionalidades realizadas nas subclasses concretas.
  • Concrete Builder – esta classe é responsável pela construção e pela montagem das partes do produto por meio da implementação da classe builder. Ela define e mantém o controle da representação que a classe cria, além de fornecer uma interface para recuperação do produto.
  • Director – esta é a classe que controla o algoritmo responsável por gerar o objeto do produto final. Um objeto Director é instanciado e seus métodos construtores são chamados. O método inclui um parâmetro para capturar objetos específicos do tipo Concrete Builder que serão então utilizados para gerar o produto (product). Dessa forma, o director, chama os métodos do concrete builder na ordem correta para gerar o objeto produto.
  • Product – o product representa o objeto complexo que está sendo construído. O concrete builder então constrói a representação interna do produto e define o processo pelo qual essa classe será montada. Na classe product são incluídas outras classes que definem as partes que a constituem, dentre elas, as interfaces para a montagem das partes no resultado final.

Como tudo funciona no mundo Builder?

Primeiramente, o client (cliente) poderá ser de certa forma, ou um objeto a parte ou mesmo o cliente real que chamará o método main() da aplicação, iniciando assim as classes Builder e Director. A classe Builder representa o nosso objeto complexo que precisa ser construído em termos de objetos e tipos mais simples. O construtor da classe Director recebe um objeto Builder como sendo um parâmetro através do cliente e é responsável por chamar os métodos apropriados da classe Builder. A fim de fornecer a classe cliente com uma interface para todos os construtores concretos, a classe Builder deve ser uma classe abstrata. Desta forma, podemos adicionar novos tipos de objetos apenas definindo a estrutura e reutilizando a lógica para o processo real da construção. O cliente é o único que precisa saber sobre os novos tipos, já a classe Director, precisa saber apenas quais os métodos que precisará chamar.

De acordo com a Figura 1, temos uma representação gráfica com relação ao padrão Builder.

Representação gráfica do modelo UML do padrão Builder

Figura 1. Representação gráfica do modelo UML do padrão Builder.

Exemplo de onde podemos utilizar o Builder

Podemos encontrar este padrão sendo utilizado, por exemplo, na implementação do framework NHibernate, onde temos a noção do builder fazendo uso da classe NHibernate.Cfg.Configuration. Esta classe nos permite colocar todo o código da construção ou validação em um único ponto e, em seguida, executarmos este código em tempo real e em locais di ...

Quer ler esse conteúdo completo? Tenha acesso completo