Menu
Coddy logo textTech

Padrão Adapter

Parte da seção Programação Orientada a Objetos do Journey de PHP da Coddy. Lição 76 de 91.

O padrão Adapter é um padrão de projeto estrutural que permite que objetos com interfaces incompatíveis trabalhem juntos. Ele atua como uma ponte entre duas interfaces, traduzindo chamadas de um formato para outro.

Imagine que você está criando uma aplicação que processa pagamentos e precisa integrar uma biblioteca de pagamentos de terceiros. A biblioteca funciona perfeitamente, mas sua interface não corresponde ao que o seu código espera. Em vez de reescrever toda a sua aplicação, você cria um adaptador que faz a tradução entre os dois.

<?php
// A interface que sua aplicação espera
interface PaymentProcessor {
    public function pay(float $amount): string;
}

// Biblioteca de terceiros com uma interface diferente
class StripeAPI {
    public function createCharge(int $cents, string $currency): string {
        return "Charged {$cents} {$currency} via Stripe";
    }
}

O adaptador implementa a interface esperada por você, enquanto usa internamente a classe de terceiros:

<?php
class StripeAdapter implements PaymentProcessor {
    public function __construct(private StripeAPI $stripe) {}
    
    public function pay(float $amount): string {
        $cents = (int)($amount * 100);
        return $this->stripe->createCharge($cents, 'USD');
    }
}

$stripe = new StripeAPI();
$processor = new StripeAdapter($stripe);
echo $processor->pay(29.99);

Saída:

Charged 2999 USD via Stripe

O adaptador converte dólares em centavos e chama o método apropriado. O código da sua aplicação conhece apenas PaymentProcessor, permanecendo felizmente alheio aos requisitos específicos do Stripe. Se mais tarde você mudar para um provedor de pagamentos diferente, basta criar um novo adaptador sem alterar seu código existente.

challenge icon

Desafio

Fácil

Vamos criar um sistema de conversão de temperatura usando o Padrão Adapter. Você tem um sensor de temperatura legado que fornece leituras em Fahrenheit, mas sua aplicação meteorológica moderna espera todas as temperaturas em Celsius. Em vez de modificar qualquer um dos sistemas, você criará um adapter que faz a conexão entre eles.

Você organizará seu código em quatro arquivos:

  • TemperatureSensor.php: Defina uma interface TemperatureSensor que sua aplicação meteorológica espera. Ela deve ter um método getTemperature(): float que retorna a temperatura em Celsius.
  • LegacySensor.php: Crie uma classe LegacySensor que simula o hardware antigo. Essa classe tem uma interface diferente da que sua aplicação precisa:
    • Ela recebe uma leitura em Fahrenheit em seu construtor (use a promoção de construtor)
    • Ela tem um método readFahrenheit(): float que retorna o valor armazenado em Fahrenheit
  • LegacySensorAdapter.php: Inclua tanto a interface TemperatureSensor quanto a classe LegacySensor. Crie uma classe LegacySensorAdapter que implementa TemperatureSensor e encapsula um LegacySensor. Seu adapter deve:
    • Aceitar um LegacySensor em seu construtor
    • Implementar getTemperature() lendo o valor em Fahrenheit do sensor legado e convertendo-o para Celsius usando a fórmula: (fahrenheit - 32) * 5 / 9
  • main.php: Inclua o arquivo LegacySensorAdapter. Você receberá uma entrada: uma temperatura em Fahrenheit.

    Crie um LegacySensor com a temperatura de entrada e, em seguida, encapsule-o em um LegacySensorAdapter. Chame getTemperature() no adapter e imprima o resultado arredondado para duas casas decimais.

    O formato da saída deve ser: Temperature: [celsius]C

Este desafio demonstra como o Padrão Adapter permite integrar interfaces incompatíveis sem modificar o código existente. Sua aplicação meteorológica trabalha exclusivamente com a interface TemperatureSensor, sem saber que as leituras reais vêm de um sensor legado em Fahrenheit.

Experimente você mesmo

<?php
require_once 'LegacySensorAdapter.php';

// Ler entrada
$fahrenheit = floatval(trim(fgets(STDIN)));

// TODO: Crie um LegacySensor com a temperatura de entrada
// TODO: Envolva-o em um LegacySensorAdapter
// TODO: Chame getTemperature() no adaptador
// TODO: Imprima o resultado arredondado para duas casas decimais
// Formato de saída: Temperature: [celsius]C

?>
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos

Pratique por conta própria: Compilador de PHP online