Ao longo dos anos, vários paradigmas buscaram cada vez mais uma maior reutilização de código, tornando assim as aplicações finais mais poderosas com um menor esforço do programador.
Porém a reutilização de código, bem como o projeto orientado a objetos, são tarefas difíceis de serem realizadas, sendo apenas conseguido com eficiência por projetistas experientes.
Surgiu daí então a idéia da criação de catálogos de padrões de projeto, os quais são uma espécie de manual de boas práticas a serem seguidas e utilizadas em projetos de software orientados a objetos. Dos catálogos mais conhecidos e utilizados, destaca-se o primeiro e considerado mais importante, escrito em 1995 pela Gang of Four, ou mais conhecida como GoF, e que também será o foco deste artigo.
As soluções orientadas a objetos, desde o seu início, sempre buscaram através dos mecanismos de herança uma maior reaproveitamento e reutilização de código.
Porém, se projetar código orientado a objetos já é difícil, mais difícil ainda é projetar software orientado a objetos com código reutilizável. Projetistas experientes conseguem visualizar a reutilização facilmente na fase de projeto de uma aplicação, enquanto projetistas novatos têm mais dificuldade para conseguir este nível de abstração de dados a ponto de visualizar um padrão dentro do software.
Isso ocorre por que um projetista experiente, por ter trabalhado em vários projetos e visto vários sistemas diferentes, consegue encontrar padrões em códigos, de classes e de comunicação entre objetos.
Daí surgiu a idéia de padrões de projetos. Os padrões de projeto (do inglês Design Patterns) são soluções para problemas recorrentes no desenvolvimento de sistemas de software orientado a objetos. Sinopse dos Design Patterns da "Gang of Four"
Padrões de Criação
Padrões que têm a ver com a instanciação de objetos
- Abstract Factory - Provê uma interface para criar famílias de objetos relacionados ou inter-dependentes sem especificar suas classes concretas.
- Builder - Separa a construção de um objeto complexo da sua representação de forma que o mesmo processo de construção possa criar representações diferentes.
- Factory Method - Define uma interface para criar um objeto, mas deixa as subclasses decidirem qual classe instanciar. O padrão Factory Method deixa uma classe repassar a responsabilidade de instanciação para subclasses.
- Prototype - Especifica os tipos de objetos a criar usando uma instância-protótipo e cria novos objetos copiando este protótipo.
- Singleton - Garante que uma classe tenha uma única instância e provê um ponto global de acesso à instância.
- Padrões Estruturais - Padrões que têm a ver com a composição de classes ou objetos
- Adapter - Converte a interface de uma classe em outra interface com a qual os clientes estão prontos para lidar. O padrão Adapter permite que classes trabalhem conjuntamente apesar de interfaces incompatíveis.
- Bridge - Desacopla uma abstração de sua implementação de forma que as duas possam mudar independentemente uma da outra.
- Composite - Compõe objetos em estruturas de árvore para representar hierarquias Parte-Todo. O padrão Composite permite que clientes tratem objetos individuais e composições de objetos de uniformemente.
- Decorator - Adiciona responsabilidades a um objeto dinamicamente. Decoradores provêem uma alternativa flexível à herança para estender funcionalidade.
- Façade - Provê uma interface unificada para um conjunto de interfaces num subsistema. O padrão Façade define uma interface de mais alto nível, deixando o subsistema mais fácil de usar.
- Flyweight - Usa o compartilhamento para dar suporte eficiente ao uso de um grande número de objetos de granularidade pequena.
- Proxy - Provê um objeto procurador ou placeholder para um outro objeto para controlar o acesso a ele.
- Padrões de Comportamento - Padrões que caracterizam formas de interação entre classes e objetos
- Chain of Responsibility - Evita acoplar o enviador de um pedido ao receptor dando oportunidade a vários objetos para tratarem do pedido. Os objetos receptores são encadeados e o pedido é passado na cadeia até que um objeto o trate.
- Command - Encapsula um pedido num objeto, permitindo assim parametrizar clientes com pedidos diferentes, enfileirar pedidos, fazer log de pedidos, e dar suporte a operações de undo.
- Interpreter - Dada uma linguagem, define uma representação de sua gramática e um interpretador que usa a representação da gramática para interpretar sentenças da linguagem.
- Iterator - Provê uma forma de acessar os elementos de uma coleção de objetos seqüencialmente sem expor sua representação subjacente.
- Mediator - Define um objeto que encapsule a forma com a qual um conjunto de objetos interagem. O padrão Mediator promove o acoplamento fraco evitando que objetos referenciem uns aos outros explicitamente e permite que suas interações variem independentemente.
- Memento - Sem violar o princípio de encapsulamento, captura e externaliza o estado interno de um objeto de forma a poder restaurar o objeto a este estado mais tarde.
- Observer - Define uma dependência um-para-muitos entre objetos de forma a avisar e atualizar vários objetos quando o estado de um objeto muda.
- State - Permite que um objeto altere seu comportamento quando seu estado interno muda. O objeto estará aparentemente mudando de classe com a mudança de estado.
- Strategy - Define uma família de algoritmos, encapsula cada um, e deixe-os intercambiáveis. O padrão Strategy permite que o algoritmo varie independentemente dos clientes que o usam.
- Template Method- Define o esqueleto de um algoritmo numa operação, deixando que subclasses completem algumas das etapas. O padrão Template Method permite que subclasses redefinem determinadas etapas de um algoritmo sem alterar a estrutura do algoritmo.
- Visitor- Represente uma operação a ser realizada nos elementos de uma estrutura de objetos. O padrão Visitor permite que se defina uma nova operação sem alterar as classes dos elementos nos quais a operação age.