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.