Padrões de Projeto - Design Patterns


No artigo - Padrões de Projeto : O modelo MVC - Model View  Controller - após falar em padrões de projetos ou Design Patterns recebi alguns emails indagando sobre mais detalhes a respeito de Design Patterns. Neste artigo espero estar atendendo a estes pedidos..

Afinal de onde vieram e o que são realmente Design Patterns ? (daqui para frente , Padrões de Projeto.)

Padrões de projeto podem ser vistos como uma solução que já foi testada para um problema. Desta forma , um padrão de projeto geralmente descreve uma solução ou uma instância da solução que foi utilizada para resolver um problema específico. Padrões de projetos  são soluções para problemas que alguém um dia teve e resolveu aplicando um modelo que foi documentado e que você pode adaptar integralmente ou de acordo com necessidade de sua solução.

Nota: Em uma definição mais formal : "Padrões para arquitetura de software são soluções de eficiência já comprovadas e amplamente utilizadas para a resolução de problemas comuns em projeto de software. Estas soluções são desenvolvidas e conhecidas por especialistas e tornam-se padrões por serem reutilizadas várias vezes em vários projetos e por terem eficácia comprovada."

Podemos considerar que a idéia original de Design Patterns surgiu com Christopher Alexander quando ele propôs a criação de catálogos de padrões para arquitetura.(Ele era Engenheiro Civil). Suas publicações a respeito foram:

Com a palavra Christopher Alexander :

"Um padrão descreve um problema que ocorre inúmeras\par vezes em determinado contexto, e descreve ainda a solução para esse problema, de modo que essa solução possa ser utilizada sistematicamente em distintas situações." [Alexander78]

Partindo do trabalho de Alexander profissionais de software começaram a incorporar esses princípios na criação das primeiras documentações de padrões de projetos como um guia para desenvolvedores iniciantes. O resultado prático foi a publicação de - Design Patterns : Elements of Reusable Object-Oriented Software - em 1995 por Eric Gamma, Richard Helm , Ralph Johnson e John Vlissides - (gang of four). Este livro é a referência principal no assunto para a comunidade de software . Nele são descritos 23 padrões que foram baseados na experiência dos autores.

Nota: No Super CD.NET você encontra a edição eletrônica do bestseller  "Design Patterns" - publicação voltada a desenvolvedores que utilizam a metodologia de orientação a objetos.

Principais propriedades dos padrões de projetos

Dentre as principais propriedades dos padrões de projetos podemos citar:

1- capturam o conhecimento e a experiência de especialistas em projeto de software.
2- especificam abstrações que estão acima do nível de classes ou objetos isolados ou de componentes [Gamma et al 1995].
3- definem um vocabulário comum para a discussão de problemas e soluções de projeto [Gamma et al 1995].
4- facilitam a documentação e manutenção da arquitetura do software [Buschmann et al 1996].
4- auxiliam o projeto de uma arquitetura com determinadas propriedades [Buschmann et al 1996].
5- auxiliam o projeto de arquiteturas mais complexas.

Dentre os principais benefícios para que a utilização dos padrões de projeto seja justificada estão :

- fornecem soluções que já foram testadas e aprovadas.
- Tornam o sistema mais fácil de entender e manter
- Facilitam o desenvolvimento de módulos coesos.
- A comunicação entre os participantes do projeto fica mais eficiente

Quando e como utilizar padrões de projetos

A primeira coisa que você tem que ter é bom senso. Faça a sua parte , implemente sua solução e veja se ela funciona. A seguir verifique se ela pode ser otimizada , se for o caso utilize o padrão de projeto que se ajusta ao seu caso para melhorar as deficiências verificadas no seu projeto.
Naturalmente isto será tão mais fácil se você tiver uma visão global do seu projeto e seu funcionamento.

Lembre-se : padrões de projeto não são uma varinha mágica que vai tornar o seu projeto isento de falhas. Se for mal implementado eles podem até diminuir a compreensão do seu projeto e aumentar a quantidade de código . Portanto padrões de projeto não resolvem todos os problemas de design de projetos.

Os componentes de um padrão de projeto são :

1- Nome - descreve a essência do padrão
2- Objetivo - descreve como o padrão atua.
3- Problema - descreve o problema
4- Solução - descreve a solução
5- Conseqüências - descreve os benefícios da utilização do padrão.

Requisitos de um bom sistema de padrões:

O sistema deve conter uma boa quantidade de padrões.
A descrição dos padrões deve seguir um formato padronizado.
O sistema deve ser estruturado, organizando os padrões seguindo critérios bem definidos.
O sistema deve mostrar o relacionamento entre os padrões.
O sistema deve estar estruturado de modo a poder evoluir.

Os tipos estão divididos por afinidade. Estou definindo apenas os mais usados. Os principais tipos de padrões de projetos são :

1- Padrões de Criação (Creational)
     
Abstract Factory - Um método Factory é um método que fabrica objetos de um tipo particular; Um objeto Factory é um objeto que encapsula                                métodos Factory.
     Builder -
Separa a construção de um objeto complexo da sua representação, de forma que o mesmo processo de construção possa criar diferentes representações.
     Factory Method -
É uma interface para instanciação de objetos que mantém isoladas as classes concretas usadas da requisição da criação destes objetos.
     Prototype -
O padrão Prototype fornece uma outra maneira de se construir objetos de tipos arbitrários.
     Singleton.
- Garante que para uma classe específica só possa existir uma única instância, a qual é acessível de forma global e uniforme.
2- Padrões de Estrutura (Structural)
    
 Adapter - Permite que dois objetos se comuniquem mesmo que tenham interfaces incompatíveis.
     Bridge -
Desacopla a interface da implementação ; Ocultação de detalhes de implementação dos clientes.
     Composite -
lida com uma estrutura de elementos agrupada hierarquicamente (não como meras coleções).
     Decorator -
Atribui responsabilidade adicionais a um objeto dinamicamente. O Decorator fornece uma alternativa flexível a subclasses para a extensão da funcionalidade.
     Facade -
Interface unificada para um subsistema ; Torna o subsistema mais fácil de usar.
     Flyweight -
Usa compartilhamento para dar suporte a vários objetos de forma eficiente.
     Proxy -
Fornece um objeto representante ou procurador de outro objeto para controlar o acesso ao mesmo.
3- Padrões de Comportamento (Behavioral)
    
Chain of Responsability - Evita dependência do remetente(cliente) de uma requisição ao seu destinatário , dando a oportunidade de mais de objeto tratar a requisição.
    Command - Associa uma ação a diferentes objetos através de uma interface conhecida.
    Interpreter -
Usado para ajudar uma aplicação a entender uma declaração de linguagem natural e executar a funcionalidade da declaração.
    Iterator -
Provê uma forma de percorrermos os elementos de uma coleção sem violar o seu encapsulamento.
    Mediator -
Cria um objeto que age como um  mediador controlando a interação entre um conjunto de objetos.
    Memento -
Torna possível salvar o estado de um objeto de modo que o mesmo possa ser restaurado.
    Observer -
Define uma relação de dependência 1:N de forma que quando um certo objeto (assunto) tem seu estado modificado os demais (observadores) são notificados; Possibilita baixo acoplamento entre os objetos observadores e o assunto.
    State -
Permite objeto alterar seu comportamento quando estado interno muda.
    Strategy -
Permite que uma família de algoritmos seja utilizada de modo independente e seletivo.
    Template Method -
Define o esqueleto de um algoritmo em uma operação adiando a definição de alguns passos para a subclasse.
    Visitor -
Define operações independentes a serem realizadas sobre elementos de uma estrutura.

A seguir temos dois exemplos práticos de utilização dos conceitos de relacionados a  padrões de projetos:

1-) Encapsulamento (escondendo os dados)

Problema a resolver: campos expostos podem ser manipulados diretamente a partir de código externo, levando a violações da invariante de representação ou a dependências indesejáveis que impedem a alteração da implementação.

Solução apresentada pelo padrão: esconda alguns componentes, permitindo apenas acessos estilizados ao objeto. Desvantagens: a interface pode não (eficientemente) fornecer todas as operações desejadas.

Desvantagens: a interface pode não (eficientemente) fornecer todas as operações desejadas. O acesso indireto pode reduzir a performance.

2-) Derivação de classes (herança)

Problema a resolver : abstrações similares possuem membros similares (campos e métodos). Esta repetição é tediosa, propensa a erros, e uma dor de cabeça durante a manutenção.

Solução apresentada pelo padrão: derive membros padrão de uma superclasse; em tempo de execução, selecione a implementação correta através de resoluções a respeito de qual implementação deve ser executada.

Desvantagens: o código de uma classe acaba ficando distribuído em várias, reduzindo o potencial de compreensão. A utilização de resoluções em tempo de execução introduz overhead (processamento extra).

"Porque, assim como relâmpago sai do oriente e se  mostra até o ocidente, assim será também a vinda do Filho do homem." Mateus 24:27

referências :

[1] ALEXANDER, C., ISHIKAWA, S., SILVERSTEIN, M., JACOBSON, M., FIKSDAHL-KING, I., ANGEL, S. "A Pattern Language". New York, NY (USA): Oxford University Press, 1977.
[2] COOPER, J. W. ”Using Design Patterns". CACM, junho, 1998, Vol.41 No. 6, pp 65-68.
[3] COPLIEN, J. O. "Software Patterns". New York, NY (USA): SIGS Books, 1996.

[4] GAMMA, E., HELM, R., JOHNSON, R., VLISSIDES, J. "Design Patterns: Elements of Reusable Object-Oriented Software". Reading, MA: Addison Wesley, 1995.
[5] GEARY, D. ”A look at the Composite pattern". IN JavaWorld, setembro, 2002. [http://www.javaworld.com/javaworld/jw-09-2002/jw-0913-designpatterns_p.html].
[6] JANDL, P. Jr. “Mais Java”. São Paulo, SP: Futura, 2003.
[7] LARSSON, J. L., MOLLER, F. “Algorithm = Iterator + Visitor”. IN Journal of Object-Oriented Programming, dezembro, 2001.


José Carlos Macoratti