Padrões de projeto em .NET - Introdução

 

O que é um padrão de projeto?

Segundo Christopher Alexander, “cada padrão descreve um problema no nosso ambiente e o cerne da sua solução, de tal forma que você possa usar essa solução mais de um milhão de vezes, sem nunca faze-lo da mesma maneira”. Embora Alexander estivesse se referindo a padrões em construções e cidades, o que ele diz é perfeitamente aplicável quando falamos em padrões de projetos orientados a objeto. Nossas soluções são expressas em termos de objetos e interfaces em vez de paredes e janelas, mas no coração de ambos os tipos de padrões está a solução para um problema em um determinado contexto.

 

Catálogo de padrões de projeto

O catálogo abaixo contém 23 padrões de projeto. Seus nomes e intenções são listados para dar uma visão geral.

 

Abstract Factory: Fornece uma interface para criação de famílias de objetos relacionados ou dependentes sem especificar suas classes concretas.

 

Adapter: Converte a interface de uma classe em outra interface esperada pelos clientes. O Adapter permite que certas classes trabalhem em conjunto, pois de outra forma seria impossível por causa de sua interfaces incompatíveis.

 

Bridge: Separa uma abstração da sua implementação, de modo que as duas possam variar independentemente.

 

Builder: Separa a construção de um objeto complexo da sua representação, de modo que o mesmo processo de construção possa criar diferentes representações.

 

Chain of Responsibility: Evita o acoplamento do remetente de uma solicitação ao seu destinatário, dando a mais de um objeto a chance de tratar a solicitação. Encadeia os objetos receptores e passa a solicitação ao longo da cadeia até que um objeto a trate.

 

Command: Encapsula uma solicitação como um objeto, permitindo que você parametrize clientes com diferentes solicitações, enfileire ou registre solicitações e suporte operações que podem ser desfeitas.

 

Composite: Compõe objetos em estrutura de árvore para representar hierarquias do tipo parte-todo. O Composite permite que os clientes tratem objetos individuais e composições de objetos de maneira uniforme.

 

Decorator: Atribui responsabilidades adicionais a um objeto dinamicamente. Os decorators fornecem uma alternativa flexível a subclasses para extensão da funcionalidade.

 

Facade: Fornece uma interface unificada para um conjunto de interfaces em um subsistema. O Facade define uma interface de nível mais alto que torna o subsistema mais fácil de usar.

 

Factory Method: Define uma interface para criar um objeto, mas deixa as subclasses decidirem qual classe a ser instanciada. O Factory Method permite a uma classe postergar a instanciação às subclasses.

 

Flyweight: Usa compartilhamento para suportar grandes quantidades de objetos, de granularidade fina, de maneira eficiente.

 

Interpreter: Dada uma linguagem, define uma representação para sua gramática juntamente com um interpretador que usa a representação para interpretar sentenças nessa linguagem.

 

Iterator: Fornece uma maneira de acessar seqüencialmente os elementos de uma agregação de objetos sem expor sua representação subjacente.

 

Mediator: Define um objeto que encapsula a forma como um conjunto de objetos interage. O Mediator promove o acoplamento fraco ao evitar que os objetos se refiram explicitamente uns aos outros, permitindo que você varie suas interações independentemente.

 

Memento: Sem violar o encapsulamento, captura e externaliza um estado interno de um objeto, de modo que o mesmo possa, posteriormente, ser restaurado para este estado.

 

Observer: Define uma dependência um-para-muitos entre objetos, de modo que, quando um objeto muda de estado, todos os seus dependentes são automaticamente notificados e atualizados.

 

Prototype: Especifica os tipos de objetos a serem criados usando uma instância prototípica e cria novos objetos copiando esse protótipo.

 

Proxy: Fornece um objeto representante, ou um marcador de outro objeto, para controlar o acesso ao mesmo.

 

Singleton: Garante que uma classe tenha somente uma instância e fornece um ponto global de acesso a ela.

 

State: Permite que um objeto altere seu comportamento quando seu estado interno muda. O objeto parecerá ter mudado de classe.

 

Strategy: Define uma família de algoritmos, encapsula cada um deles e os torna intercambiáveis. O Strategy permite que o algoritmo varie independentemente dos clientes que o utilizam.

 

Template Method: Define o esqueleto de um algoritmo em uma operação, postergando a definição de alguns passos para subclasses. O Template Method permite que as subclasses redefinam certos passos de um algoritmo sem mudar sua estrutura.

 

Visitor: Representa uma operação a ser executada sobre os elementos da estrutura de um objeto. O Visitor permite que você defina uma nova operação sem mudar as classes dos elementos sobre os quais opera.

 

Organizando o catálogo

Os padrões de projeto variam na sua granularidade e no seu nível de abstração. Como existem muitos padrões de projeto, precisamos organizá-los. A classificação ajuda a aprender os padrões mais rapidamente, bem como direcionar esforços na descoberta de novos.

 

Os padrões de projeto são classificados por dois critérios: O primeiro critério, chamado finalidade, reflete o que o padrão faz. Os padrões podem ter finalidade de criação, estrutural ou comportamental. Os padrões de criação se preocupam com o processo de criação de objetos. Os padrões estruturais lidam com a composição de classes ou de objetos. Os padrões comportamentais caracterizam as maneiras pelas quais classes ou objetos interagem e distribuem responsabilidades.

 

O segundo critério, chamado escopo, especifica se o padrão se aplica primariamente a classes ou a objetos. Os padrões para classes lidam com os relacionamentos entre classes e suas subclasses. Esses relacionamentos são estabelecidos através do mecanismo de herança, assim eles são estáticos. Os padrões para objetos lidam com relacionamentos entre objetos que podem ser mudados em tempo de execução e são mais dinâmicos. Quase todos utilizam a herança em certa medida.

 

 

 

Propósito

 

 

De criação

Estrutural

Comportamental

Escopo

Classe

Factory Method

Adapter

Interpreter

Template Method

 

Objeto

Abstract Factory

Builder

Prototype

Singleton

Adapter

Bridge

Composite

Decorator

Façade

Flyweight

Proxy

Chain of Responsibility

Command

Iterator

Mediator

Memento

Observer

State

Strategy

Visitor

 

Os padrões de criação voltados para classes deixam alguma parte da criação de objetos para subclasses, enquanto que os padrões de criação voltados para objetos postergam esse processo para outro objeto. Os padrões estruturais voltados para classes utilizam a herança para compor classes, enquanto que os padrões estruturais voltados para objetos descrevem maneiras de montar objetos. Os padrões comportamentais voltados para classes usam a herança para descrever algoritmos e fluxo de controle, enquanto que os voltados para objetos descrevem como um grupo de objetos coopera para executar uma tarefa que um único objeto não pode executar sozinho.

 

Há outras maneiras de organizar os padrões. Alguns padrões são freqüentemente usados em conjunto. Por exemplo: o Composite é freqüentemente usado com o Iterator ou o Visitor. Alguns padrões são alternativos: o Prototype é uma alternativa para o Abstract Factory. Alguns padrões resultam em projetos semelhantes, embora tenham intenções diferentes. Por exemplo: os diagramas de estrutura de Composite e Decorator são semelhantes.

 

Existem muitas maneiras de organizar os padrões de projeto. Ter múltiplas maneiras de pensar a respeito deles aprofundará sua percepção sobre o que fazem, como se comparam e como aplicá-los.

 

Os próximos artigos estarão dissecando cada um dos 23 padrões de projetos com pequenos trechos de código em Visual Basic .NET exemplificando os mesmos. Seguindo a ordem padrões de criação, padrões estruturais e padrões comportamentais, o primeiro padrão a ser detalhado será o Abstract Factory.