O que é?

O Adapter é um padrão de projeto estrutural que tem como objetivo "traduzir" ou adaptar o funcionamento de um código X para que seja compatível com o código Y.

Imagine que você tem várias classes de pagamento que implementam uma interface comum chamada Pagamento — por exemplo: Pix, Ted e Boleto.

Agora, sua equipe precisa integrar uma nova forma de pagamento, como PayPal, desenvolvida por outra squad ou vinda de uma biblioteca de terceiros. Essa classe PayPal não implementa a interface Pagamento, e isso quebraria o padrão da sua aplicação.

Para resolver esse problema sem modificar a biblioteca externa (o que muitas vezes nem é possível), usamos o padrão Adapter, que atua como um "tradutor" entre as interfaces. Ele faz com que a classe PayPal seja compatível com a interface Pagamento, sem que a classe original precise ser alterada.

Quando usar Adapter:

  • Quando você quer usar uma classe existente, mas ela não implementa a interface esperada.
  • Quando não é possível modificar a classe original (ex: código de terceiros).

Exemplo:

public interface Pagamento {
    void pagar(double valor);
}

// CLASSE EXTERNA( NAO MODIFICAVEL)
public class PayPalApi {
    public void sendPayment(double amount) {
        System.out.println("Pagamento de R$" + amount + " feito via PayPal.");
    }
}

// Adapter mantendo o padrão de pagamentos 
// Invoca a biblioteca terceira
public class PayPalAdapter implements Pagamento {
    private PayPalApi paypal;

    public PayPalAdapter(PayPalApi paypal) {
        this.paypal = paypal;
    }

    @Override
    public void pagar(double valor) {
        paypal.sendPayment(valor); // adapta a chamada
    }
}

Se a biblioteca do PAYPAL tiver alguma alteração o código client fica desacoplado dessas alterações


🎯 Cenário 2: Leitor de Cartão SD vs. Cartão MicroSD
Sua aplicação trabalha com leitores que aceitam CartaoSD, mas agora você precisa usar um CartaoMicroSD (incompatível). Usamos um Adapter para que o CartaoMicroSD funcione no leitor padrão.

public interface CartaoSD {
    String lerDados();
}

// Classe que já funciona (padronizada)
public class CartaoSDOriginal implements CartaoSD {
    @Override
    public String lerDados() {
        return "Dados lidos do cartão SD.";
    }
}

// Classe incompatível( precisa de tradução )
public class CartaoMicroSD {
    public String acessarDados() {
        return "Dados lidos do cartão MicroSD.";
    }
} 

// Adapter 
public class MicroSDAdapter implements CartaoSD {
    private CartaoMicroSD microSD;

    public MicroSDAdapter(CartaoMicroSD microSD) {
        this.microSD = microSD;
    }

    @Override
    public String lerDados() {
        return microSD.acessarDados(); // adaptação da chamada
    }
}