terça-feira, 24 de abril de 2012

Padrão de Projeto Builder

Builder é um padrão de projeto de software que permite a separação da construção de um objeto complexo da sua representação, de forma que o mesmo processo de construção possa criar diferentes representações.


O padrão Builder, da forma como foi descrito no livro Design Patterns: Elements of Reusable Object-Oriented Software, contém os seguintes elementos:

director — constrói um objeto utilizando a interface do builder;
builder — especifica uma interface para um construtor de partes do objeto-produto;
concrete builder — define uma implementação da interface builder, mantém a representação que cria e fornece interface para recuperação do produto;
product — o objeto complexo acabado de construir. Inclui classes que definem as partes constituintes.



Diagrama UML da estrutura do padrão Builder
O padrão Builder pode ser utilizado em uma aplicação que converte o formato RTF para uma série de outros formatos e que permite a inclusão de suporte para conversão para outros formatos, sem a alteração do código fonte do leitor de RTF.

A implementação da solução para esse problema pode ser realizada através de uma classe de leitura (director) associada a uma classe capaz de converter o formato RTF para outra representação (builder). O objeto da classe de leitura lê cada token do texto e executa o método apropriado no objeto de conversão, de acordo com tipo do token. A classe de conversão possui um método para cada tipo de token, incluindo os caracteres comuns, parágrafos, fontes e etc. Para cada formato de texto suportado é criada uma classe de conversão especializada (concrete builder). Um conversor para formato ASCII, por exemplo, poderia ignorar qualquer requisição para converter tokens que não fossem caracteres comuns. Um conversor para o formato PDF, por outro lado, iria processar qualquer requisição para poder converter o estilo, além do texto.

Diagrama


Exemplo de Diagrama em UML para o Padrão Builder.

Código

Este código, escrito na linguagem Java, mostra a implementação do diagrama mostrado acima.

 abstract class ConversorTexto {
        public void converterCaractere(char c) {
                // vazio
        }
 
        public void converterParagrafo() {
                // vazio
        }
 
        public void converterFonte(Fonte f) {
                // vazio
        }
 }
 
 class ConversorPDF extends ConversorTexto {
        public void converterCaractere(char c) {
                System.out.print("Caractere PDF");
        }
 
        public void converterParagrafo() {
                System.out.print("Parágrafo PDF");
        }
 
        public void converterFonte(Fonte f) {
                System.out.print("Fonte PDF");
        }
 }
 
 class ConversorTeX extends ConversorTexto {
        public void converterCaractere(char c) {
                System.out.print("Caractere Tex");
        }
 
        public void converterParagrafo() {
                System.out.print("Paragrafo Tex");
        }
 
        public void converterFonte(Fonte f) {
                System.out.print("Fonte Tex");
        }
 }
 
 class ConversorASCII extends ConversorTexto {
        public void converterCaractere(char c) {
                System.out.print("Caractere ASCII");
        }
 }
 
 class LeitorRTF {
 
        private ConversorTexto conversor;
 
        LeitorRTF(ConversorTexto c) {
                this.conversor = c;
        }
 
        public void lerRTF() {
 
                List<Token> tokens = obterTokensDoTexto();
 
                for (Token t : tokens) {
                        if (t.getTipo() == Token.Tipo.CARACTERE) {
                                conversor.converterCaractere(t.getCaractere());
                        }
                        if (t.getTipo() == Token.Tipo.PARAGRAFO) {
                                conversor.converterParagrafo();
                        }
                        if (t.getTipo() == Token.Tipo.FONTE) {
                                conversor.converterFonte(t.getFonte());
                        }
                }
        }
 }
 
 public class Cliente {
 
        public static void main(String[] args) {
 
                ConversorTexto conversor;
                if (args[0].equals("pdf")) {
                        conversor = new ConversorPDF();
                } else if (args[0].equals("tex")) {
                        conversor = new ConversorTeX();
                } else {
                        conversor = new ConversorASCII();
                }
                LeitorRTF leitor = new LeitorRTF(conversor);
 
                leitor.lerRTF();
        }
 }


A classe Cliente determina, através do parâmetro passado ao programa Java ("pdf" para formato PDF, "tex" para Tex e qualquer outro para ASCII), qual das classes derivadas de ConversorTexto irá utilizar na construção da classe LeitorRTF.

Fonte:

- Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides. Design Patterns: Elements of Reusable Object-Oriented Software. 1 ed. Estados Unidos da América: Addison-Wesley, 1995. ISBN 0-201-63361-2
- http://pt.wikipedia.org/wiki/Builder

Postado por: Argemiro Júnior, ADS - 6º Período

Nenhum comentário:

Postar um comentário