Padrão Builder Juliana França Santos Aquino Sumário • Builder – Introdução/Propósito – Motivação – Aplicabilidade – Estrutura – Participantes – Colaborações – Conseqüências – Exemplo de Código © LES/PUC-Rio Introdução/Propósito - Um tipo de padrão criacional – Classificação GoF - Abstraem o processo de criação de objetos - Separar a construção de um objeto complexo da sua representação - O mesmo processo de construção possa criar diferentes apresentações - Criar passo a passo objetos mais complexos © LES/PUC-Rio Motivação (1/3) • Um leitor de documentos RTF (Rich Text Format) deveria ser capaz de converter RTF em outros formatos de texto: – ASCII – TeX – HTML – etc. • O número de conversões está aberto • Facilidade de acrescentar uma nova conversão sem modificar o leitor © LES/PUC-Rio Motivação (2/3) TextConverter RTFReader ConverterCharacter(char) ParseRTF() ConvertFontChange(Font) ConvertParagraph() while (t = get the next token) { switch t.Type { CHAR: builder->ConvertCharacter(t.Char) FONT: ASCIIConverter TeXConverter builder->ConvertFontChange ConverterCharacter(char) (t.Font) ConverterCharacter(char) GetASCIIText() ConvertFontChange(Font) PARA: ConvertParagraph() builder->ConvertParagraph() GetTeXText() } HTMLConverter ConverterCharacter(char) ConvertFontChange(Font) ConvertParagraph() GetHTMLText() } ASCIIText TeXText © LES/PUC-Rio HTMLText Aplicabilidade • O objeto de construção deve permitir diferentes representações para o objeto que é construído • O algoritmo para criação de um objeto complexo deve ser independente das partes que compõem o objeto e de como elas são montadas – Cliente quer construir uma casa/prédio e o builder sabe como construir a casa/prédio (ela é composta de vários passos) © LES/PUC-Rio Estrutura Director Builder Construct() BuildPart() for all objects in structure { builder->BuildPart() } ConcreteBuilder BuildPart() GetResult() © LES/PUC-Rio Product Participantes (1/2) • Builder (TextConvert) – Especifica uma interface abstrata para criação de partes de um objeto-produto ou criação de diferentes representações • ConcreteBuilder (ASCIIConverter, TeXConverter, HTMLConverter) – Constrói partes do produto pela implementação da interface do Builder – Define e mantém a representação que cria – Fornece uma interface para recuperação do produto (GetASCIIText) © LES/PUC-Rio Participantes (2/2) • Director (RTFReader) – Constrói um objeto usando a interface do Builder • Product (ASCIIText, TeXText, HTMLText) – Representa o objeto complexo em construção. ConcreteBuilder constrói a representação interna do produto e define o processo pelo qual ele é montado – Inclui classes que definem as partes constituintes, inclusive as interfaces para a montagem das partes no resultado final © LES/PUC-Rio Colaborações (1/2) • O cliente cria o objeto Director e o configura com o objeto Builder desejado • Director notifica o construtor sempre que uma parte do produto deve ser construída/convertida • Builder trata solicitações do diretor e acrescenta partes ao produto • O cliente recupera o produto do construtor © LES/PUC-Rio Colaborações (2/2) aClient aDirector aConcreteBuilder new ConcreteBuilder() new Director (aConcreteBuilder) Construct () BuildPartA() BuildPartB() BuildPartC() GetResult() © LES/PUC-Rio Conseqüências • Permite variar a representação interna de um produto • Isola o código para construção e representação • Oferece um controle mais fino sobre o processo de construção © LES/PUC-Rio Exemplo de Código (1/4) public class Cliente { public static void main(String[] args) { ConversorTexto conversor; if (args[0].equals("html")) conversor = new ConversorHTML(); else if (args[0].equals("tex")) conversor = new ConversorTeX(); else if (args[0].equals("ascii")) conversor = new ConversorASCII(); LeitorRTF leitor = new LeitorRTF(conversor); leitor.lerRTF(); } } © LES/PUC-Rio Exemplo de Código (2/4) 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(t.getParagrafo()); if (t.getTipo() == Token.Tipo.FONTE) conversor.converterFonte(t.getFonte()); } } } © LES/PUC-Rio Exemplo de Código (4/4) class ConversorTeX extends ConversorTexto { public void converterCaractere(char c) { System.out.print("Caractere TeX"); } public void converterParagrafo() { System.out.print("Parágrafo TeX"); } public void converterFonte(Fonte f) { System.out.print("Fonte TeX"); } } // Similar para ConversorHTML, ConversorASCII © LES/PUC-Rio Exemplo de Código (3/4) abstract class ConversorTexto { public void converterCaractere(char c); public void converterParagrafo(Paragrafo p); public void converterFonte(Fonte f); } © LES/PUC-Rio Obrigada!