Informações
| Tipo: | Artigo |
|---|---|
| Data de Publicação: | 07/10/2006 |
| Revisado em: | 07/10/2006 |
Vote!
Tags Relacionadas
Comentários ( 11 )
Imprimir
O Padrão de Projeto Adapter
por:
David Pereira (david@jeebrasil.com.br)
Aprenda como tornar possível a comunicação entre dois objetos com interfaces incompatíveis utilizando o padrão de projeto Adapter.
1. Introdução
O padrão de projeto Adapter é necessário quando possuímos dois objetos que precisam se comunicar mas as suas interfaces são diferentes. O adaptador é responsável por "converter" uma interface em outra tornando possível a comunicação entre os objetos.
Um exemplo típico de uma situação como estas ocorre quando é necessário conectar um dispositivo a uma tomada e o plugue do dispositivo possui um padrão diferente da tomada, tornando impossível o encaixe. Imagine, por exemplo, que você comprou um eletrodoméstico em alguma loja européia. Muito provavelmente, este possuirá um plugue parecido com o da figura 1.

Figura 1: Plugue europeu de três pinos
Isto acontece porque as tomadas em alguns países na Europa são diferentes, possuem três pinos. Mas a tomada na sua casa não é assim, ela possui apenas dois encaixes, como a da figura 2:

Figura 2: Tomada comum de dois pinos
Então você tem dois objetos, o plugue e a tomada, que possuem interfaces diferentes (o plugue possui três pinos e a tomada dois encaixes apenas), portanto eles não podem se encaixar. E agora? Como ligar o seu aparelho? A solução é utilizar um adaptador, um instrumento que "transforma" uma interface em outra - no caso, transforma um plugue de três pinos em um de dois ou uma tomada de dois encaixes em uma de três, dependendo do ponto de vista. Este adaptador pode ser visto na figura 3.

Figura 3: Adaptador
Em um projeto de software podemos enfrentar esse problema de ter que fazer a comunicação entre dois objetos com interfaces incompatíveis e, em muitas dessas vezes, não é possível ou não é conveniente modificar as classes. Para isso, teremos que fazer um adaptador para esses objetos se comunicarem e é da implementação desse adaptador que o padrão de projeto adapter trata.
2. Um exemplo...
Para explicar como é implementado o padrão de projeto adapter, vamos analisar o exemplo anterior e tentar abstrair uma implementação em Java para o mesmo.
As tomadas têm uma interface, que dizem se ela é uma tomada de dois ou de três pinos. Essa interface deve possuir um método que diz o que a tomada faz: fornecer energia elétrica. A interface das tomadas de três pinos foi chamada de TomadaTresPinos e pode ser vista na listagem 1, enquanto a interface das tomadas de dois pinos foi chamada de TomadaDoisPinos e pode ser vista na listagem 2.
public interface TomadaTresPinos {
public void fornecerEnergia();
}
Listagem 1: Interface TomadaTresPinos
public interface TomadaDoisPinos {
public void fornecerEnergia();
}
Listagem 2: Interface TomadaDoisPinos
Os plugues também deverão ter interfaces que dirão se eles são plugues de dois ou três pinos e possuirão um método para conectá-lo a uma tomada. A interface dos plugues de três pinos foi chamada de PlugueTresPinos e possui um método conectar() que possui como argumento um objeto que implementa a interface TomadaTresPinos, ou seja, um plugue de três pinos só pode conectar-se a uma tomada de três pinos. De forma semelhante, a interface dos plugue de dois pinos foi chamada de PlugueDoisPinos e o seu método conectar() possui como argumento um objeto que implementa a interface TomadaDoisPinos, que indica que um plugue de dois pinos só pode se conectar a uma tomada de dois pinos. Tais interfaces podem ser vistas nas listagens 3 e 4.
public interface PlugueTresPinos {
public void conectar(TomadaTresPinos tomada);
}
Listagem 3: Interface PlugueTresPinos
public interface PlugueDoisPinos {
public void conectar(TomadaDoisPinos tomada);
}
Listagem 4: Interface PlugueDoisPinos
Essas interfaces descrevem que tomadas podem ter dois ou três pinos, plugues podem ter dois ou três pinos, que plugues de dois pinos devem conectar-se a tomadas de dois pinos e plugues de três pinos devem conectar-se a tomadas de três pinos. Podemos ter diversas tomadas, diversos plugues de modelos, cores, fabricantes diferentes, mas que implementam essas interfaces.
Exemplos de classes que implementam essas interfaces podem ser vistas a seguir, nas listagens de 5 a 8. Os métodos a serem implementados simplesmente imprimem no console o que estão fazendo.
public class TomadaEuropeia implements TomadaTresPinos {
public void fornecerEnergia() {
System.out.println("[TOMADA] Fornecendo energia para um plugue de três pinos!");
}
}
Listagem 5: Exemplo de classe que implementa a interface TomadaTresPinos
public class TomadaComum implements TomadaDoisPinos {
public void fornecerEnergia() {
System.out.println("[TOMADA] Fornecendo energia para um plugue de dois pinos!");
}
}
Listagem 6: Exemplo de classe que implementa a interface TomadaDoisPinos
public class PlugueEuropeu implements PlugueTresPinos {
public void conectar(TomadaTresPinos tomada) {
System.out.println("[PLUGUE] Pegando energia elétrica de uma tomada de três pinos.");
tomada.fornecerEnergia();
}
}
Listagem 7: Exemplo de classe que implementa a interface PlugueTresPinos
public class PlugueComum implements PlugueDoisPinos {
public void conectar(TomadaDoisPinos tomada) {
System.out.println("[PLUGUE] Pegando energia elétrica de uma tomada de dois pinos.");
tomada.fornecerEnergia();
}
}
Listagem 8: Exemplo de classe que implementa a interface PlugueDoisPinos
Um diagrama de classes que representa este ambiente pode ser visto na figura 4.

Figura 4: Diagrama de classes das tomadas e plugues com dois e três pinos.
Precisamos encaixar um plugue de três pinos em uma tomada de dois pinos, portanto deveremos usar um adaptador. Como construí-lo?
- O adaptador irá converter a interface de uma tomada de dois pinos em uma tomada de três pinos, portanto o adaptador irá comportar-se como uma tomada de três pinos, ou seja, o adaptador deve implementar TomadaTresPinos.
- Criamos no adaptador uma referência para o objeto adaptado (a tomada de dois pinos, no caso) e fazemos a atribuição desta referência através do construtor.
- Implementamos os métodos da interface TomadaTresPinos de forma a traduzir o comportamento da interface adaptada.
Podemos ver a implementação na listagem 9.
public class Adaptador implements TomadaTresPinos {
private TomadaDoisPinos tomada;
public Adaptador(TomadaDoisPinos tomada) {
this.tomada = tomada;
}
public void fornecerEnergia() {
tomada.fornecerEnergia();
}
}
Listagem 9: Implementação do adaptador
Podemos agora fazer com que um plugue de três pinos se conecte a uma tomada de dois pinos através de um adaptador. Para isso, basta criar três objetos: uma tomada de dois pinos, um plugue de três pinos e o adaptador, passando o objeto adaptado (a tomada de dois pinos) no construtor. Em seguida, é só chamar o método conectar() do plugue passando como parâmetro o adaptador. O código pode ser visto na listagem 10.
public class Main {
public static void main(String[] args) {
TomadaDoisPinos tomada = new TomadaComum();
PlugueTresPinos plugue = new PlugueEuropeu();
Adaptador adapter = new Adaptador(tomada);
plugue.conectar(adapter);
}
}
Listagem 10: Testando o adaptador
O diagrama de classes que representa essa situação pode ser visto na figura 5.

Figura 5: Diagrama de classes com o adaptador
3. Definindo o adapter
O Adapter (também conhecido como Wrapper) é um padrão de projeto do GoF [1] e é classificado como um padrão estrutural. Possui o objetivo de “converter a interface de uma classe em outra interface, esperada pelos clientes. O Adapter permite que classes com interaces imcompatíveis trabalhem em conjunto – o que, de outra forma, seria impossível.” [1]
Um diagrama de classes descrevendo a estrutura do Adapter pode ser visto na figura 6. Nessa figura, definimos quatro entidades: o Alvo, que é a interface que você quer usar; o Cliente, que é o objeto que irá interagir com a interface alvo; O Adaptado, que é a interface que precisa ser adaptada para a interface Alvo e o Adapter, que “transforma” a interface do Adaptado na interface Alvo. No exemplo acima, a interface Alvo é a TomadaTresPinos, o Cliente é o PlugueTresPinos, o Adapter é o Adaptador e o Adaptado é a TomadaDoisPinos.

Figura 6: Estrutura do Adapter - Diagrama de Classes
O funcionamento do adapter é simples. O Cliente precisa comunicar-se com o Adaptado, mas possuem interfaces incompatíveis. Então, ele comunica-se com o Adapter, fazendo a este uma solicitação. O Adapter repassa a solicitação para o Adaptado. O Adaptado precisa então devolver uma resposta para o Cliente, mas novamente não é possível devido a imcompatibilidade de interfaces. A solução é enviar a resposta para o Adapter que irá em seguida encaminhá-la para o Cliente, completando assim o ciclo de comunicação [2]. Esse funcionamento pode ser traduzido em um diagrama de seqüências como o mostrado na figura 7.

Figura 7: Funcionamento do Adapter - Diagrama de Seqüência
4. Referências
[1] Gamma, Erich; Helm, Richard; Johnson, Ralph; Vlissides, John. Padrões de Projeto – Soluções reutilizáveis de Software Orientado a Objetos . Bookman, 2004.
[2] Freeman, Eric; Freeman, Elisabeth. Head First Design Patterns . O'Reilly, 2004.
Comentários (11)
- Muito bom o exemplo de vocês sobre o Design Pattern estrutural Adapter... Meus parabéns pelo tutorial e continuando postando coisas aqui... Seria interessante postarmos coisas sobre J2ME e JSE aqui no site.. tipo.. sermos uma plataforma de software. Fica aí minha sugestão. Forte abraço.
- postado por Lucas Abrão em 13/12/2006 às 23:21
- Mto boa o exemplo escolhido. Até mais []'s
- postado por Diego Falcão em 04/04/2007 às 23:21
- Por que não disponibilizar em PDF ?
- postado por Alessandro Bezerra Moreira em 17/05/2007 às 23:21
- Muito bom exemplo perfeito me ajucou muito parabens
- postado por Fernando Lima em 12/06/2007 às 23:21
- Eu com dúvidas em relação,de como implementar o um padrão java(Adpter) em programa que construir.
- postado por Glaucia em 20/06/2007 às 23:21
- Ótimo o exemplo, parabéns!!
- postado por Karina Moura em 11/09/2007 às 23:21
- Exemplo fantástico, me ajudou muito. Obrigado!!!
- postado por Rafael Teixeira em 17/09/2007 às 23:21
- Continue postando... Muito bom!!! Existe mais padrões... fale sobre eles !!! Meus parabéns
- postado por Alessandro Delon em 12/12/2007 às 23:21
- Bem Esplicado, um exemplo simples ajuda muito mais a entender e fixar conceitos do que exemplos complexos.
- postado por anderson em 25/05/2008 às 23:21
- Excelente artigo, e o exemplo muito bem pensado! Me ajudou bastante, Muito Obrigado!
- postado por Gabriel Such em 06/06/2008 às 23:21
- Sou novo no assunto de padrões e me surgiu uma dúvida, para utilizar a tomada no método fornecerEnergia não deveria ter this como segue abaixo: public class Adaptador implements TomadaTresPinos { private TomadaDoisPinos tomada; public Adaptador(TomadaDoisPinos tomada) { this.tomada = tomada; } public void fornecerEnergia() { this.tomada.fornecerEnergia(); } }
- postado por Hebert Freitas em 12/09/2008 às 23:21
