segunda-feira, 27 de junho de 2011

Design Patterns

Artigo traduzido de http://sourcemaking.com/design_patterns

Na engenharia de software, um design pattern (padrão de projeto) é uma solução geral para um problema comum de ocorrer no design de software. Um design pattern não é um projeto concluído que possa ser transformado diretamente em código. É uma descrição ou modelo (de como resolver um problema) que pode ser usado em muitas situações diferentes.

Design patterns podem acelerar o processo de desenvolvimento, oferecendo paradigmas de desenvolvimento testados e provados. Um projeto de software eficaz deve prever questões para que não haja problemas na implementação. O reúso dos design patterns ajuda a prevenir problemas maiores, além de melhorar a legibilidade do código para os programadores e arquitetos familiares com os patterns.

As pessoas freqüentemente sabem aplicar somente algumas técnicas de projeto de software para sanar certos problemas. Estas técnicas são difíceis de aplicar a uma gama mais ampla de problemas. Design patterns oferecem soluções gerais, documentadas em um formato que não requer especificidades ligadas a um problema particular.

Além disso, os patterns permitem aos desenvolvedores se comunicarem utilizando nomes conhecidos nas interações de software. Podem-se melhorar os design pattterns ao longo do tempo, os tornando mais robustos que designs ad-hoc (significado: para resolver determinado problema ou realizar uma tarefa específica).

Creational Design Patterns: dizem respeito à instanciação de classes. Podem ser divididos em patterns de criação de classes e patterns de criação de objetos. Enquanto os patterns de criação de classes utilizam herança no processo de instanciação, os patterns de criação de objetos utilizam delegação. Nomes dos design patterns criacionais (que serão explicados em outros posts): Abstract Factory, Builder, Factory Method, Object Pool, Prototype, Singleton.

Structural design patterns: dizem respeito à composição da classe e do objeto. Os patterns estruturais de classes utilizam herança para compor interfaces. Os patterns estruturais de objetos definem formas de compor objetos a fim de obter uma nova funcionalidade. Nomes dos design patterns estruturais (que serão explicados em outros posts): Adapter, Bridge, Composite, Decorator, Facade, Flyweight, Private Class Data, Proxy.

Behavioral design patterns: dizem respeito à comunicação dos objetos da classe. Nomes dos design patterns estruturais (que serão explicados em outros posts): Chain of responsibility, Command, Interpreter, Iterator, Mediator, Memento, Null Object, Observer, State, Strategy, Template method, Visitor.


Críticas:

O conceito de design patterns tem sido criticado por algumas correntes da ciência da computação.

a) Aponta o problema errado: a necessidade de padrões resultam do uso de linguagens de computador ou técnicas com habilidade de abstração ineficiente. Num projeto ideal, um conceito não deve ser copiado, mas meramente referenciado. Mas se algo é referenciado em vez de copiado, não há padrão para rotular e catalogar. Paul Graham assim escreve em Revenge of the Nerds.

Peter Norvig também tem um argumento similar. Ele demonstra que 16 em 23 patterns no livro Design Patterns (que é primariamente focado em C++) são simplificados ou eliminados (através do suporte direto da linguagem) em Lisp ou Dylan.

Carece de fundamentos formais: o estudo dos design patterns têm sido excessivamente ad hoc, e alguns argumentam que o conceito necessita ter um posicionamento mais formal. Na OOPSLA 1999, a Gang of Four foi submetida a um "julgamento", em que foi "condenada" por ⅔ dos "jurados" que participaram do "julgamento" por "crimes contra a ciência da computação".

Leva a soluções ineficientes: a idéia do design pattern é uma tentativa de padronizar o que já é considerado melhor prática. Em princípio isto pode parecer benéfico, mas na prática sempre resulta na duplicação desnecessária de código. É quase sempre mais eficaz utilizar uma implementação bem feita do que um "mero design pattern".

Não difere significantemente de outras abstrações: alguns autores alegam que os design patterns não diferem significantemente de outras formas de abstração, e que o uso da nova terminologia (emprestada da comunidade de arquitetura) para descrever o fenômeno existente no campo da programação é desnecessário. O paradigma Model-View-Controller é aclamado como um exemplo de um "pattern" que precede em muitos anos o conceito de "design patterns". Também há o argumento de que a contribuição primária da comunidade Design Patterns (e o livro da Gang of Four) foi o uso do padrão de Alexander como uma forma de documentação; uma prática que freqüentemente é ignorada na literatura.

Creational patterns

Artigo traduzido de http://sourcemaking.com/creational_patterns.

Na engenharia de software, design patterns criacionais lidam com mecanismos de criação de objetos. A intenção é criar objetos da forma apropriada à situação, uma vez que forma básica da criação de objetos pode resultar em problemas de design ou adicionar complexidade ao design. Os design patterns criacionais resolvem este problema controlando de alguma maneira a criação do objeto:

  • Abstract Factory: Cria uma instância de diversas famílias de classes.

  • Builder: Separa a construção do objeto de sua representação.

  • Factory Method: Cria uma instância de diversas classes derivadas.

  • Object Pool: Evita aquisição e liberação custosa de recursos através da reciclagem de objetos que não estão mais em uso.

  • Prototype: Uma instância completamente inicializada que é copiada ou clonada.

  • Singleton: Uma classe onde somente uma instância pode existir.

Regras importantes:

Às vezes, padrões de criação são concorrentes: há casos em que Prototype ou Abstract Factory podem ser usados de forma benéfica. Em outros momentos, são complementares: Abstract Factory pode armazenar um conjunto de Prototypes onde os objetos são clonados e retornados; o Builder pode usar um dos outros padrões para implementar os componentes que são construídos. Abstract Factory, Builder e Prototype podem usar Singleton na sua implementação.
  1. Abstract Factory, Builder e Prototype definem um objeto de fábrica que é responsável por conhecer e criar a classe de objetos de produto e o torna um parâmetro do sistema. Abstract Factory tem o objeto de fábrica produzindo objetos de diversas classes. Builder tem o objeto de fábrica que constrói um produto complexo incrementalmente, usando um protocolo complexo correspondente. Prototype tem o objeto de fábrica (aka prototype) que constrói um produto através da cópia de um objeto de protótipo.

  2. As classes da Abstract Factory são implementadas por Factory Methods, mas também podem ser implementadas usando Prototype.

  3. Abstract Factory pode ser utilizada como uma alternativa à Facade para esconder classes específicas da plataforma.

  4. Builder foca na construção passo a passo de um objeto complexo. Abstract Factory enfatiza a família de objetos de produto (simples ou complexos). Enquanto no Builder o produto é retornado como uma etapa final, no Abstract Factory o produto é retornado imediatamente.

  5. Builder está para criação assim como Strategy está para algoritmo.

  6. Builder sempre constroem um Composite.

  7. Factory Methods são normalmente chamados dentro de Template methods.

  8. Factory Method: criação através de herança. Prototype: criação através de delegação.

  9. O design freqüentemente começa usando Factory Method (menos complicado, mais customizável, subclasses proliferam) e evolui para Abstract Factory, Prototype ou Builder (mais flexíveis, porém mais complexos) conforme o designer descobre onde é necessária uma maior flexibilidade.

  10. Prototype não requer subclasse, mas requer uma operação Initialize. Factory Method requer subclasse, mas não requer Initialize.

  11. Designs que utilizam padrões Composite e Decorator podem também obter benefícios do Prototype.