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
}
}