Tags: , | Categories: Padrões de Projeto Posted by Rafael on 30/12/2010 19:16 | Comentários (0)

Conversando hoje com um companheiro de equipe, percebi que um código exemplo fez falta no post anterior. Pensando nisso, desenvolvi um exemplo em C#, o qual vocês podem baixar aqui: Blog.DP.Adapter.zip (19,40 kb). Esse código de exemplo implementa o exemplo proposto no post anterior, seguindo o seguinte diagrama:

Um detalhe interessante nesse exemplo é o uso de um Factory Method, ou seja, um método que retorna a instância que se deseja. No nosso caso, uma instância da classe Adaptador12para34 é retornada, para evidenciarmos a chamada do método da classe adaptada Torneira12 (adaptee) através da interface Adaptador12para34. Abordaremos o padrão FactoryMethod em um próximo post com maiores detalhes e exemplos.

Ao executarmos o código, a seguinte mensagem é apresentada:

Note que essa mensagem encontra-se dentro do método Acoplar12(), dentro da classe Torneira12. Note também que, na classe Program que contém o método Main, associamos a instância da classe Adaptador12para34, que implementa a interface ITerminal34, retornada pelo Factory Method à variável terminal, e invocamos o método Acoplar() da instância, que, por sua vez, invoca o método Acoplar12 da classe Torneira12.

Temos assim a implementação do padrão Adapter, através da criação de uma interface (Adaptador12para34) que estabelece o acesso ao objeto implementado fora do padrão (Torneira12), para o padrão da aplicação, de forma transparente para o cliente, que no nosso exemplo é a classe Program.

Espero que esse exemplo auxilie no entendimento do padrão Adapter.

Até a próxima!

Tags: , | Categories: Padrões de Projeto Posted by Rafael on 28/12/2010 21:34 | Comentários (2)

Dando sequencia à nossa série sobre Padrões de Projeto, vamos falar um pouco sobre o padrão estrutural Adapter. Esse padrão, também conhecido como Wrapper, tem como objetivo criar uma interface comum entre classes, ou seja, classes com interfaces diferentes podem trabalhar em conjunto desde que uma interface adaptadora seja criada para tal fim.

Muitos já fizeram ou fazem uso desse padrão com freqüência no dia-a-dia, principalmente se fazem uso de frameworks ou toolkits de terceiros. Na maioria das vezes, existem classes que foram projetadas para serem reutilizadas, porém, isso não é possível pois elas não atendem a uma interface específica de um objeto de nossa aplicação. Para resolvermos esse problema, criamos uma interface adaptadora para que as classes possam trabalhar em conjunto.

Fazendo uma analogia bem simples, porém interessante, podemos imaginar que a nossa aplicação seja um sistema hidráulico residencial. Quando necessitamos trocar uma torneira (um componente do nosso sistema), por qualquer que seja o motivo, precisamos nos certificar se o tamanho da rosca da torneira (interface terceiro) é compatível com o tamanho do terminal (interface local) do encanamento. Caso o tamanho seja diferente, precisamos utilizar um adaptador (a nova interface criada) para que uma das interfaces seja igual a outra, e o conjunto funcione perfeitamente.

O padrão Adapter é o único padrão cujo escopo abrange tanto Classe quanto Objeto. Os diagramas abaixo, retirados do livro Padrões de Projeto, da GoF, base para todos os posts de padrões de projeto, ilustra bem a diferença entre Classe e Objeto:

Um adaptador de classe usa a herança múltipla para adaptar uma interface à outra:

Padrão Adapter - Escopo Classe

Um adaptador de objeto depende da composição de objetos:

Padrão Adapter - Escopo Objeto

Para finalizar, vamos retomar o nosso exemplo sobre o sistema hidráulico residencial. Consideremos que o tamanho dos tubos do sistema hidráulico, ou encanamento, da nossa residência seja padrão 3/4 de uma polegada, e queiramos utilizar uma torneira que tenha um tamanho 1/2 de uma polegada (nota: o tamanho 3/4 [0,75 polegadas] é 50% maior do que o tamanho 1/2 [0,5 polegadas]). Precisamos utilizar um adaptador que estabeleça uma interface entre 1/2 e 3/4 polegadas, ou seja, uma interface que adapte (adapter) a interface da torneira de 1/2 polegadas (adaptee) para uma interface definida especificamente (target) para o domínio do encanamento (cliente), que é 3/4 polegadas.

Assim, temos:

Espero que esse exemplo simples tenha facilitado o entendimento do padrão Adapter.

Até a próxima!