Adapter

Origem: Wikipédia, a enciclopédia livre.
Saltar para a navegação Saltar para a pesquisa
Ambox rewrite.svg
Esta página precisa ser reciclada de acordo com o livro de estilo (desde outubro de 2016).
Sinta-se livre para editá-la para que esta possa atingir um nível de qualidade superior.
Edit-delete-not encyclopedic3.svg
Este artigo ou parte de seu texto pode não ser de natureza enciclopédica. (desde outubro de 2016)
Justifique o uso dessa marcação e tente resolver essas questões na página de discussão.
Question book.svg
Este artigo ou secção não cita fontes confiáveis e independentes (desde janeiro de 2014). Ajude a inserir referências.
O conteúdo não verificável pode ser removido.—Encontre fontes: Google (notícias, livros e acadêmico)

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.

Exemplo de diagrama do padrão Adapter

Descrição das classes de acordo com o diagrama UML[editar | editar código-fonte]

  • Target (Alvo): define a interface do domínio específico que o cliente utiliza.
  • Adapter (Adaptador): adapta a interface Adaptee para a interface da classe Target.
  • Adaptee (Adaptada): define uma interface existente que necessita ser adaptada.
  • Client (Cliente): colabora com os objetos em conformidade com a interface Target.

Consequências[editar | editar código-fonte]

Cada adaptador de classes e de objetos tem diferentes soluções de compromisso. Um adaptador de classe:

  • adapta a classe Adaptee a Target através do uso efetivo de uma classe Adapter concreta. Em consequência disso, um adaptador de classe não funcionará quando quisermos adaptar uma classe e todas as suas subclasses;
  • permite que a classe Adapter substitua algum comportamento da classe Adaptee, uma vez que Adapter é uma subclasse de Adaptee;
  • introduz somente um objeto, e não é necessário endereçamento indireto adicional por ponteiros para chegar até a classe Adaptee.

Um adaptador de objeto:

  • permite a um único Adapter trabalhar com muitos Adaptees, ou seja, o Adaptee em si e todas as suas subclasses (caso existam);
  • torna mais difícil redefinir um comportamento de uma classe Adaptee. Ele exigirá a criação de subclasses de Adaptee e fará com que a classe Adapter referencie a subclasse, ao invés da classe Adaptee em si.

Motivação[editar | editar código-fonte]

Muitas 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.

Aplicabilidade[editar | editar código-fonte]

O padrão Adapter pode ser utilizado quando:

  • se deseja utilizar uma classe existente, porém sua interface não corresponde à interface que se necessita;
  • o desenvolvedor quiser criar classes reutilizáveis que cooperem com classes não-relacionadas ou não-previstas, ou seja, classes que não possuem necessariamente interfaces compatíveis;
  • (exclusivamente para adaptadores de objetos) é necessário utilizar muitas subclasses existentes, porém, impossível de adaptar essas interfaces criando subclasses para cada uma. Um adaptador de objeto pode adaptar a interface de sua classe mãe.

Exemplos[editar | editar código-fonte]

Adaptador de Objeto[editar | editar código-fonte]

Código em Java e Diagrama UML de classes[editar | editar código-fonte]

Um exemplo do padrão adapter, onde adaptamos a EntradaPS2 para EntradaUSB
 1 //Classe adaptada (Adaptee)
 2 class SensorXbox2 {
 3 
 4     //Solicitação Especifica
 5     public void conectarXbox2() {
 6         System.out.println("Um novo controle foi conectado ao sensor do Xbox.");
 7     }
 8 }
 9 
10 //Classe alvo (Target)
11 class SensorPS5 {
12 
13     //Solicitação
14     public void conectarPS5() {
15         System.out.println("Um novo controle foi conectado ao sensor do PS5.");
16     }
17 }
18 
19 //Classe adaptador (Adapter)
20 class AdaptadorPS5ParaXbox2 extends SensorPS5 {
21 
22     private SensorXbox2 adaptee;
23 
24     public AdaptadorPS5ParaXbox2(SensorXbox2 adaptee) {
25         this.adaptee = adaptee;
26     }
27 
28     //Override da solicitação
29     public void conectarPS5() {
30         adaptee.conectarXbox2();
31         System.out.println("But stadia wins!");
32     }
33 }
34 
35 //Classe Cliente(Client)
36 public class ControlePS5 {
37 
38     private SensorPS5 sensorAQueSeConecta;
39     
40     public void Conectar(SensorPS5 sensor){
41         this.sensorAQueSeConecta = sensor;
42         sensorAQueSeConecta.conectarPS5();
43     }
44 
45 //}
46 //public class Teste{
47     public static void main(String[] args) {
48         
49         //Tem-se um Xbox2 e mas deseja-se usar um controle ps5:
50         SensorXbox2 adaptee = new SensorXbox2();
51         ControlePS5 target = new ControlePS5();
52         
53         //Cria-se um falso sensor de PS5 que, na verdade, traduz e repassa os comandos para o Xbox em questão:
54         AdaptadorPS5ParaXbox2 adapter = new AdaptadorPS5ParaXbox2(adaptee);
55         
56         //Conecta-se o controle ao adapter:
57         target.Conectar(adapter);
58     }
59 }
60 
61 //Saída:
62 //Um novo controle foi conectado ao sensor do Xbox.
63 //But stadia wins!

Código em C#[editar | editar código-fonte]

 1 using System;
 2 using static System.Console;
 3 
 4 //Classe adaptada (Adaptee)
 5 class SensorXbox2
 6 {
 7     //Solicitação Especifica
 8     public virtual void ConectarXbox2()
 9     {
10         WriteLine("Um novo controle foi conectado ao sensor do Xbox.");
11     }
12 }
13 
14 //Classe alvo (Target)
15 class SensorPS5
16 {
17     //Solicitação
18     public virtual void ConectarPS5()
19     {
20         WriteLine("Um novo controle foi conectado ao sensor do PS5.");
21     }
22 }
23 
24 //Classe adaptador (Adapter)
25 class AdaptadorPS5ParaXbox2 : SensorPS5
26 {
27     private SensorXbox2 adaptee;
28 
29     public AdaptadorPS5ParaXbox2(SensorXbox2 adaptee)
30     {
31         this.adaptee = adaptee;
32     }
33 
34     //Override da solicitação
35     public override void ConectarPS5()
36     {
37         adaptee.ConectarXbox2();
38         WriteLine("But stadia wins!");
39     }
40 }
41 
42 //Classe Cliente(Client)
43 class ControlePS5
44 {
45     private SensorPS5 sensorAQueSeConecta;
46     
47     public void Conectar(SensorPS5 sensor)
48     {
49         this.sensorAQueSeConecta = sensor;
50         sensorAQueSeConecta.ConectarPS5();
51     }
52 
53 //}
54 //
55 //class Test
56 //{
57     static void Main()
58     {
59         //Tem-se um Xbox2 e mas deseja-se usar um controle ps5:
60         SensorXbox2 adaptee = new SensorXbox2();
61         ControlePS5 target = new ControlePS5();
62         
63         //Cria-se um falso sensor de PS5 que, na verdade, traduz e repassa os comandos para o Xbox em questão:
64         AdaptadorPS5ParaXbox2 adapter = new AdaptadorPS5ParaXbox2(adaptee);
65         
66         //Conecta-se o controle ao adapter:
67         target.Conectar(adapter);
68     }
69 }
70 
71 //Saída:
72 //Um novo controle foi conectado ao sensor do Xbox.
73 //But stadia wins!

Adaptador de Classe[editar | editar código-fonte]

Código em Java e diagrama UML de classes[editar | editar código-fonte]

A classe adaptador adapta a InterfaceCliente e a ClasseExistente
class 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#[editar | editar código-fonte]

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 relacionados[editar | editar código-fonte]

O 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.

Ícone de esboço Este artigo sobre Informática é um esboço. Você pode ajudar a Wikipédia expandindo-o.