De que se trata o artigo

O artigo trata da implementação do design pattern Builder, um padrão criacional que se tornou popular após o lançamento do livro “Padrões de Projeto: Elementos de Software Orientado a Objetos Reutilizável”, da famosa “Gangue dos quatro” (ou GoF, em inglês).


Para que serve

Todo projeto precisa criar instâncias de classes, mas se isto não for feito de forma controlada, o projeto tende a tornar-se complexo e rígido, dificultando a manutenção do mesmo. Os padrões criacionais são técnicas que ajudam controlar como as instâncias de classes são criadas.


Em que situação o tema é útil

O Padrão Builder é útil quando você se deparar com um objeto complexo que precisa de muitas informações para ser criado. Neta situação o Padrão Builder é capaz de simplificar a criação deste objeto ao mesmo tempo em que adiciona mais flexibilidade ao projeto e controla como as instâncias de classes são criadas.

Builder

Criar softwares seguindo os princípios de orientação a objetos bem como os padrões de projeto é meio caminho rumo ao software eficiente. Mas nem sempre é fácil identificar quando e onde aplicar um princípio ou padrão de projeto. A melhor maneira de identificar onde usar um ou outro dos diversos padrões existentes é, em primeiro lugar, conhecer o máximo de padrões possíveis. Neste artigo você aprenderá como implementar o Padrão Builder.

Talvez um dos livros mais importantes (pelo menos o mais famoso), sobre os padrões de projetos seja “Design patterns: elements of reusable object-oriented software” (em português, “Padrões de Projeto: Elementos de Software Orientado a Objetos Reutilizável”), publicado em 1994. Nele os autores Erich Gamma, Richard Helm, Ralph E. Johnson e John Vlissides descrevem 23 padrões de projetos divididos em três categorias: padrões criacionais, padrões estruturais e padrões comportamentais.

Estes padrões normalmente trabalham juntos, pois dificilmente você terá um problema cuja solução seja simplesmente implementar um determinado padrão. Na maioria das vezes, você precisa compreender o conceito apresentado pelo padrão. Só assim você será capaz de interpretá-lo e identificar situações para usá-lo no seu projeto.

Os 23 padrões publicados neste livro receberam o apelido de padrões GoF (Gang of Four – Gangue dos Quatros), devido aos quatro autores do livro. “Design patterns: elements of reusable object-oriented software” difundiu o conceito de padrões de projeto, que até aquela época estava sob o domínio de poucos. Por conta disto, a publicação do livro é considerada por muitos como um divisor de águas.

Os padrões GoF são os padrões mais populares, mas existem outros como, por exemplo os padrões GRASP (General Responsibility Assignment Software Patterns - Padrões de Princípios Gerais para Atribuição de Responsabilidade). Dentre os vários padrões GRASP, os mais populares são: Creator, Information Expert (ou apenas Expert) e Controller. Enquanto os padrões GoF exploram soluções bem específicas, os padrões GRASP exploram as práticas e princípios da orientação a objetos.

Do que é feito um padrão

Um padrão de projeto não passa de uma solução flexível e reutilizável para um problema de projeto. Digo “problema de projeto”, por que os padrões de projetos não são soluções para o software em si, por exemplo, um padrão de projeto não diz como um software deve estabelecer conexão com o banco de dados, mas ele diz como o projeto deve ser codificado para que a camada de conexão seja flexível o máximo possível. Enfim, um padrão de projeto soluciona um problema de projeto.

Além de abordar e solucionar um problema de forma a tornar o projeto mais flexível, um padrão ainda precisa ter um nome e uma descrição das consequências – boas e/ou ruins – da sua implementação. Todo padrão de projeto terá no mínimo estas quatro características: nome, problema, solução e conseqüências:

• Nome: resume o problema, a solução e/ou a conseqüência do uso;

• Problema (ou motivação): descreve a situação de projeto em que o padrão pode ajudar se for implementado;

• Solução (ou intenção): mostra como aplicar os padrões descrevendo quais são os participantes (classes), do padrão e qual o papel de cada um;

• Consequências: descreve qual o impacto no projeto devido ao uso deste padrão – é normal que um padrão tenha consequências boas e também ruins.

O nome diz muito a respeito de um padrão. Quando você lê “Padrão Observer”, o que mais poderia pensar além de que este padrão faz uma classe observar outra classe. O que não é possível saber apenas olhando o nome do padrão é como ele faz o que diz fazer. Para isto serve a descrição do problema em que ele se aplica.

A descrição do problema é sempre a mais abstrata possível, para que qualquer programador de qualquer linguagem seja capaz de compreendê-la. Isto quer dizer que você não vai encontrar uma descrição de problema como esta: “Se você estiver precisando criar projeto com a capacidade de trocar de aparência, use o padrão Abstract Factory.”. Não teria graça se fosse assim. Uma descrição mais real é: “Se precisar criar uma família de objetos sem depender de quem são os integrantes desta família ou de como eles são criados, use o padrão Abstract Factory.”. A diferença é que a primeira frase descreve UM PROBLEMA, enquanto que a segunda frase descreve O PROBLEMA que o padrão Abstract Factory pode ajudar a resolver.

Depois de interpretar a descrição do problema e concluir que ele pode ajudar o seu projeto, você vai precisar conhecer quais são as consequências de usá-lo. Talvez você ache que as consequências são ruins ou que uma das consequências seria “cara demais” para o projeto – se chegar a esta conclusão o melhor a fazer é procurar por outro padrão, pois diversos padrões diferentes podem solucionar um mesmo problema, cada um com suas consequências – boas e ruins – de uso.

Por fim, resta a descrição da solução, cujo objetivo é explicar como implementar o padrão de projeto. A descrição da solução é tão abstrata quanto a descrição do problema, por isso é necessário interpretar a solução ao invés de decorá-la. A solução apresenta, por meio de um diagrama de classes, quais são os participantes (as classes), da solução além de uma explicação de qual é o papel de cada participante.

As categorias

Além das características que você leu no último tópico “Do que é feito um padrão”, os padrões de projetos GoF também pertencem a uma destas três categorias: criacionais, estruturais e comportamentais:

• Criacionais: oferecem mecanismos diferentes para separar a criação de objetos;

• Estruturais: definem maneiras de criar composições complexas ou adicionar comportamentos a um objeto sem necessariamente precisar alterar o código da classe;

• Comportamentais: padrões especializados em comunicação entre os objetos – definem maneiras dos objetos se comunicarem sem precisar conhecer muito (ou nada), um do outro.

Os padrões comportamentais são voltados a comunicação entre os objetos e classes. Um projeto tende a entrar em colapso quando a comunicação e interação entre seus objetos e classes não está bem projetada. Os padrões GoF definem 11 padrões comportamentais, cujos mais populares são: Command, Observer, Strategy e Iterator.

Já com os padrões estruturais você consegue usar da herança para criar interfaces compostas. Isto significa ter a capacidade de usar a composição de objetos para criar novas funcionalidades em tempo de execução.

Os padrões criacionais, que inclui o Builder, são padrões com objetivo de diminuir a dependência do construtor das classes, isto quer dizer que, quando se implementa um padrão criacional o número de instruções como esta “TMinhaClasse.Create” tende a diminuir. Veja a seguir.

Padrões criacionais

Usar o construtor das classes sem controle é considerado uma prática ruim. O princípio de orientação orientada a objetos “Programe Para Interfaces” defende que, um projeto reutilizável deve ser baseado no uso das interfaces, e não das implementações, porém, toda vez que o construtor de uma classe é usado, obviamente uma implementação está sendo criada, já que apenas elas podem ser instanciadas por um construtor.

Por outro lado, como é possível usar uma classe sem invocar o seu construtor? Este é um problema de projeto pelo qual você não precisa passar, pois a solução para ele foi encontrada, testada e documentada. Hoje esta solução é usada por milhares de programadores em todo o mundo: são os padrões criacionais.

Nota: O problema relacionado ao uso do construtor das classes é apenas um dos problemas cujos padrões criacionais ajudam amenizar.

Objetos complexos

O objetivo do Padrão Builder é facilitar a criação de objetos complexos. Alguns objetos necessitam mais do que uma simples instrução TMinhaClasse.Create para funcionar corretamente. Na Listagem 1 ...

Quer ler esse conteúdo completo? Tenha acesso completo