Adapter
Adapter (Adaptador, ou também conhecido como Wrapper) é um dos padrões de projeto estruturais do GoF (Gang of Four). De forma exemplificável por um adaptadores de cabos, o padrão Adapter converte a interface de uma classe para outra interface que o cliente espera encontrar, "traduzindo" solicitações do formato requerido pelo usuário para o formato compatível com o a classe adaptee e as redirecionando. Dessa forma, o Adaptador permite que classes com interfaces incompatíveis trabalhem juntas. Veja a aba exemplos. Descrição das classes de acordo com o diagrama UML
ConsequênciasCada adaptador de classes e de objetos tem diferentes soluções de compromisso. Um adaptador de classe:
Um adaptador de objeto:
MotivaçãoMuitas vezes uma classe que poderia ser reaproveitada não é reutilizada justamente pelo fato de sua interface não corresponder à interface específica de um domínio requerida por uma aplicação. AplicabilidadeO padrão Adapter pode ser utilizado quando:
Adaptador de ObjetoCódigo em Java e Diagrama UML de classes//Classe adaptada (Adaptee)
class SensorXbox2 {
//Solicitação Especifica
public void conectarXbox2() {
System.out.println("Um novo controle foi conectado ao sensor do Xbox.");
}
}
//Classe alvo (Target)
class SensorPS5 {
//Solicitação
public void conectarPS5() {
System.out.println("Um novo controle foi conectado ao sensor do PS5.");
}
}
//Classe adaptador (Adapter)
class AdaptadorPS5ParaXbox2 extends SensorPS5 {
private SensorXbox2 adaptee;
public AdaptadorPS5ParaXbox2(SensorXbox2 adaptee) {
this.adaptee = adaptee;
}
//Override da solicitação
public void conectarPS5() {
adaptee.conectarXbox2();
System.out.println("But stadia wins!");
}
}
//Classe Cliente(Client)
public class ControlePS5 {
private SensorPS5 sensorAQueSeConecta;
public void Conectar(SensorPS5 sensor){
this.sensorAQueSeConecta = sensor;
sensorAQueSeConecta.conectarPS5();
}
//}
//public class Teste{
public static void main(String[] args) {
//Tem-se um Xbox2 e mas deseja-se usar um controle ps5:
SensorXbox2 adaptee = new SensorXbox2();
ControlePS5 target = new ControlePS5();
//Cria-se um falso sensor de PS5 que, na verdade, traduz e repassa os comandos para o Xbox em questão:
AdaptadorPS5ParaXbox2 adapter = new AdaptadorPS5ParaXbox2(adaptee);
//Conecta-se o controle ao adapter:
target.Conectar(adapter);
}
}
//Saída:
//Um novo controle foi conectado ao sensor do Xbox.
//But stadia wins!
Código em C#using System;
using static System.Console;
//Classe adaptada (Adaptee)
class SensorXbox2
{
//Solicitação Especifica
public virtual void ConectarXbox2()
{
WriteLine("Um novo controle foi conectado ao sensor do Xbox.");
}
}
//Classe alvo (Target)
class SensorPS5
{
//Solicitação
public virtual void ConectarPS5()
{
WriteLine("Um novo controle foi conectado ao sensor do PS5.");
}
}
//Classe adaptador (Adapter)
class AdaptadorPS5ParaXbox2 : SensorPS5
{
private SensorXbox2 adaptee;
public AdaptadorPS5ParaXbox2(SensorXbox2 adaptee)
{
this.adaptee = adaptee;
}
//Override da solicitação
public override void ConectarPS5()
{
adaptee.ConectarXbox2();
WriteLine("But stadia wins!");
}
}
//Classe Cliente(Client)
class ControlePS5
{
private SensorPS5 sensorAQueSeConecta;
public void Conectar(SensorPS5 sensor)
{
this.sensorAQueSeConecta = sensor;
sensorAQueSeConecta.ConectarPS5();
}
//}
//
//class Test
//{
static void Main()
{
//Tem-se um Xbox2 e mas deseja-se usar um controle ps5:
SensorXbox2 adaptee = new SensorXbox2();
ControlePS5 target = new ControlePS5();
//Cria-se um falso sensor de PS5 que, na verdade, traduz e repassa os comandos para o Xbox em questão:
AdaptadorPS5ParaXbox2 adapter = new AdaptadorPS5ParaXbox2(adaptee);
//Conecta-se o controle ao adapter:
target.Conectar(adapter);
}
}
//Saída:
//Um novo controle foi conectado ao sensor do Xbox.
//But stadia wins!
Adaptador de ClasseCódigo em Java e diagrama UML de classesclass ClasseExistente {
public void exibir() {
System.out.println("Metodo exibir()");
}
}
interface InterfaceCliente {
public void mostrar();
}
class Adaptador extends ClasseExistente implements InterfaceCliente {
public void mostrar() {
exibir();
}
}
public class Cliente
{
public static void Main(string[] args)
{
InterfaceCliente existente = new Adaptador();
existente.mostrar();
}
}
Código em C#namespace PadraoAdapter
{
//Adaptada(adaptee)
public class ClasseExistente
{
public void Exibir()
{
Console.Write("Metodo exibir()");
}
}
//Adaptada(adaptee)
public interface InterfaceCliente
{
void Mostrar();
}
//Adaptador(adapter)
public class Adaptador : ClasseExistente, InterfaceCliente
{
public void Mostrar()
{
Exibir();
}
}
class Cliente
{
static void Main(string[] args)
{
InterfaceCliente existente = new Adaptador();
existente.mostrar();
}
}
}
Padrões relacionadosO padrão GoF Bridge possui uma estrutura similar a um adaptador de objeto propriamente dito, mas esse padrão tem uma intenção diferente: tem como objetivo separar uma interface da sua implementação, de uma forma que elas possam variar fácil e independentemente. Um adaptador do padrão Adapter se destina a mudar a interface de um objeto existente. Outro padrão estrutural GoF que podemos citar é o Decorator, que por sua vez, aumenta outro objeto sem mudar sua interface. Desta forma, um Decorator é mais transparente para a aplicação do que um adaptador de Adapter. Como consequência, o Decorator suporta a composição recursiva, a qual não é possível com adaptadores puros. Por fim, o padrão Proxy, que também é um padrão estrutural, permite a definição de um representante ou “procurador” para outro objeto e não muda sua interface. |