Archive for janeiro, 2010
27 de janeiro de 2010
Design Patterns – Patterns Criacionais: Builder
escrito por Ruppel, enquanto EngenheiroA segunda pattern explicada no livro Design Patterns é o builder. Ela é muito parecida com a pattern AbstractFactory explicada no post anterior, mas ela possui um foco diferente.
O intuito desta pattern é separar o processo de criação de um objeto da sua representação. Assim, um objeto complexo, que exigiria algumas etapas para sua construção, pode ter um builder genérico que serviria para diferentes representações desse objeto.
O exemplo utilizado no livro é de um leitor de formato RTF. Esse leitor pode criar uma outra representação do formato RTF de várias maneiras: em puro texto, em formatação alternativas como o LeX, ou até em representações gráficas. Cada uma dessas representações é um produto distinto, mas, em todas elas, o processo de conversão a partir do RTF analisaria o texto sequencialmente, e executaria processos especiais para coisas como: mudança de fonte, mudança de parágrafo, inserção de caracteres especiais e etc.
O diagrama de classes abaixo ilustra como é a solução oferecida por esta pattern.
Na ilustração não está o papel do cliente. O interesse do cliente é obter um Produto. Para isso ele precisará ter conhecimento do Diretor (genérico) e do Builder, mas reparem que o Cliente precisa conhecer o builder concreto e não apenas o abstrato. Isso porque o método GetResult não está declarado na interface Builder.
Esta pattern, portanto, torna o seu sistema dependente do produto final. O que a pattern vai abstrair é o processo de criação do produto, guiado pela implementação do método Construct pelo Diretor (que vai construindo as partes do produto, sem precisar conhecer sequer qual é a interface do produto).
É decisivo nesta pattern a escolha de um processo de criação do produto com uma granularidade fina o suficiente para a criação das diferentes representações do Produto. Isso pode ser um problema para alguns dos builders concretos mais simples, que necessitem implementar várias partes vazias desse processo. Um jeito interessante de se fazer o Builder para evitar isso é através de métodos BuildPart vazios, para que os builders concretos implementem apenas os processos que lhe são interessantes.
Eu confesso nunca vi esta pattern em ação, mas fazendo uma comparação com a AbstractFactory vejo duas diferentes:
- O builder está focado na construção do objeto na forma de passos (partes)
- O cliente fica dependente da classe concreta do builder (não é um defeito, a pattern foi feita propositadamente desta forma, a intenção era permitir diferentes conjuntos de construção e representação para um produto conhecido)
16 de janeiro de 2010
Design Patterns – Patterns Criacionais: Abstract Factory
escrito por Ruppel, enquanto EngenheiroPatterns Criacionais
A Abstract Factory é a primeira Design Pattern descrita no livro Design Patterns. Ela faz parte da categoria de Patterns Criacionais, cujo objetivo é a instanciação de objetos. Essa categoria é importante pois ela sustenta o princípio mais importante do livro: “programe para interfaces e não para implementações”.
Todas as patterns tratam a respeito de relações entre os objetos, de forma que eles sejam independentes das implementações. Porém, em algum momento esses objetos deverão ser instanciados, e aí entram em cena as Patterns Criacionais, cujo único objetivo é a instanciação de objetos de forma que seu sistema continue independente de implementações.
Posso dizer que, atualmente, essas patterns criacionais estão em desuso, sendo substituídas pelos frameworks de Injeção de Dependência, que fazem exatamente isso: instanciam para você as classes das quais você é dependente. De toda forma, conhecer as patterns, a sua motivação e entender as suas consequências é um bom exercício de design de software.
Abstract Factory
O problema específico que a AbstractFactory tenta resolver é da instanciação na existência de uma família de produtos. O exemplo dado no livro é o seguinte: você tem elementos visuais (produtos), como Window, ScrollBar, Menu e etc. Esses elementos visuais têm diferentes implementações para cada família de implementação gráfica, como o Microsoft Windows, o MAC, e X do Linux.
Nesse caso, a solução consiste de duas coisas:
1. Crie interfaces padrões para os diferentes produtos dessa família (como Window, ScrollBar e Menu). E todo o seu sistema vai trabalhar apenas com essas interfaces que você definiu.
2. Defina uma AbstractFactory, que tem os métodos de instanciação para cada uma dessas interfaces padrões definidas acima, no caso, os métodos para o exemplo seriam: CreateWindow, CreateScrollBar, CreateMenu. Toda hora que o seu sistema precisa de instâncias dos produtos ele as obterá através dessa AbstractFactory. Algo como factory.CreateWindow()
Mas de onde virá essa factory? Em algum lugar, provavelmente na inicialização do seu sistema, você define qual AbstractFactory você vai fornecer ao seu sistema, e repassa essa factory a todos os objetos que precisarem dela.
Na figura acima, retirada do livro, o Client, que representa o “resto do seu sistema”, utiliza as classes abstratas dos produtos (AbstractProductA e AbstractProductB) e a AbstractFactory, assim como foi explicado.
Prós x Contras
É importante agora analisar os benefícios e malefícios dessa pattern. O ponto principal é que a pattern deixa seu sistema independente das diferentes famílias, ou seja, garante o baixo acoplamento que foi falado no começo.
Outro ponto positivo é que a pattern permite adicionar, remover ou modificar rapidamente qual família de produtos deseja-se usar. Isso pode até ser feito em runtime, se usado com um pouco de Reflection.
O ponto negativo desse pattern é que a adição ou remoção de um produto da família exige a modificação da AbstractFactory, o que causa um grande overhead, pois deve-se modificar todas as implementações da factory e o cliente que usa a AbstractFactory.
Na verdade, usando-se Reflection pode-se até criar um único método “Create” que recebe como parâmetro alguma indicação de qual produto ele deve criar (uma string com o nome da classe, por exemplo). Assim, você poderia criar um novo produto sem muitos problemas, basta passar o parâmetro certo para o novo produto. Mas isso funciona como uma balança: se você ganha flexibilidade na criação de novos produtos, você perde com a necessidade de uma interface única para todos esses produtos, já que eles serão retornados pelo mesmo método “Create”. E o seu client precisará fazer um cast para o produto certo.
acabo de assistir a estréia do bbb10
eu, confesso, até que gosto um pouco do bbb. Acho que por estar vendo pessoas reais em uma situação diferente. Claro que muitas vezes o negócio é bem fútil mesmo. Mas costuma ser engraçado.
mas uma coisa chamou muita a atenção: tem muito viado!
de 7 homens, são 2 viados. Acho que é bem acima da proporção de viados no Brasil. Nada contra dar espaço às minorias, mas por quê apenas a minoria de viados tem espaço? Existem outras minorias: os orientais, os velhos, os gordos. E olha o absurdo que eu ia cometendo: ia incluir os negros entre as minorias ignoradas pelo BBB.
E óbvio, os negros são uma maioria ignorada pelo BBB. É verdade que entre os ricos os negros são minoria, então o mais correto seria dizer que os pobres são uma maioria ignorada pelo BBB.
Será que se algum participante faz essa ponderação durante o programa ele sofreria punições? Expulsão do BBB? Um processo jurídico (sustentado por algum contrato maléfico?) Uma multa?
E de fato, qual seria a maior punição? Se houvesse uma punição explícita o tiro poderia sair pela culatra: a mídia faria barulho e o participante corajoso seria enaltecido.
O melhor seria ignorar o comentário. Não exibi-lo no horário nobre. E, de uma forma fria e calculista, forçar o público a não gostar do participante. Pegar frases fora do contexto. Criar sensacionalismo nessas frases. Encontrar incoerências entre coisas ditas. Enfim, essa seria a maior punição.
Design Patterns
escrito por Ruppel, enquanto EngenheiroPara estrear a série “Resumo dos clássicos da computação” começarei pelo consagrado Design Patterns, escrito por Erich Gamma, Richard Helm, Ralph Johnson e John Vlissides.
O livro Design Patterns é um dos maiores, se não o maior, dos clássicos em desenvolvimento de software. Seus autores ficaram imortalizados como “a gangue dos quatro”.
O primeiro capítulo do livro serve para explicar o que são Design Patterns. Traduzindo o termo para o português teríamos “Padrão de Projeto”, uma tradução bem razoável. As design patterns são padrões desenvolvidos para sistemas orientados a objetos (conhecer OO é requisito mínimo para ler este livro).
As design patterns não foram inventadas pela gangue dos quatro, o trabalho deles foi identificar e catalogar esses padrões de projeto usados em diferentes sistemas em operação pelo mundo. Eles identificaram esses padrões, as situações em que eram usados e ainda vantagens e desvantagens do uso de cada padrão. Esse catálogo que fez do livro um clássico: ele virou referência para análise de qualquer outro sistema.
E afinal, o que é uma design pattern? Design pattern é uma forma de se estruturar os objetos do seu sistema OO para resolver um tipo de problema recorrente. Assim, a mesma design pattern pode ser usada para diversos casos distintos, desde que apresentem algumas características em comum, encaixando-se no “tipo de problema” para o qual a pattern foi concebida. As designs patterns são comumente encontradas nos grandes sistemas implementados com sucesso pelo mundo afora.
Para caracterizar uma Design Pattern, ao longo do livro, eles utilizam:
1. Nome – para podermos nos referenciar de forma fácil a elas
2. Problema (ou “tipo de problema” ou “situação”) - uma caracterização de quando essa pattern deve ser usada
3. Solução – é a estruturação dos objetos de forma a resolver o problema acima descrito (quais as interfaces, como elas se relacionam e suas funções na resolução do problema)
4. Consequências – são as vantagens e desvantages da pattern, ou resultados obtidos com o uso daquela pattern
Dois conceitos fortíssimos ficam ao longo de todo o livro:
- Programe para interfaces e não para implementações, deixando seu sistema com baixo acoplamento
- Abtraia os conceitos que variam no seu sistema em forma de objeto. Por exemplo, se você tem um objeto que possui alguma lista, e em algum momento esse objeto deve ordenar essa lista, mas existem vários parâmetros que alteram a forma com a qual essa lista deve ser ordenada, então, uma boa idéia seria criar objetos para as diferentes formas de se ordenar essa lista.
Os capítulos do livro descrevem, cada um, uma Design Pattern. Nos próximos dias criarei posts para cada uma dessas Design Patterns apresentadas no livro.

