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 StripeO 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.
Desafio
FácilVamos 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 interfaceTemperatureSensorque sua aplicação meteorológica espera. Ela deve ter um métodogetTemperature(): floatque retorna a temperatura em Celsius.LegacySensor.php: Crie uma classeLegacySensorque 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(): floatque retorna o valor armazenado em Fahrenheit
LegacySensorAdapter.php: Inclua tanto a interface TemperatureSensor quanto a classe LegacySensor. Crie uma classeLegacySensorAdapterque implementaTemperatureSensore encapsula umLegacySensor. Seu adapter deve:- Aceitar um
LegacySensorem 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
- Aceitar um
main.php: Inclua o arquivo LegacySensorAdapter. Você receberá uma entrada: uma temperatura em Fahrenheit.Crie um
LegacySensorcom a temperatura de entrada e, em seguida, encapsule-o em umLegacySensorAdapter. ChamegetTemperature()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
?>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
1Fundamentos de OOP
Arquivos externosIntrodução à OOPClasses vs. objetosA palavra-chave $thisMétodosPropriedadesConstrutor (__construct)Destrutor (__destruct)Recapitulação - Calculadora simples4Herança
Herança BásicaA Palavra-chave parent::Sobrescrita de MétodosA Palavra-chave finalClasses AbstratasRecapitulação - Hierarquia de Funcionários7Encapsulamento
Público, Protegido, PrivadoModificadores de Acesso em ProfundidadeGetters e SettersOcultação de InformaçõesPromoção de Construtor (8.0)Recapitulação - Sistema de Registros de Alunos10Conceitos Avançados de OOP
Composição vs. HerançaInjeção de DependênciaClasses AnônimasEnums (PHP 8.1)Fibras (PHP 8.1)Análise Profunda da Clonagem de ObjetosGeradores e Iteradores13Padrões de Projeto Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão CompositePadrão Repository2Namespaces e Autoloading
Introdução a NamespacesA palavra-chave usePadrão de Autoloading PSR-4Autoloader do ComposerRecapitulação - Projeto organizado5Interfaces e Contratos
Introdução às InterfacesImplementando InterfacesImplementação de Múltiplas InterfacesInterface vs Classe AbstrataTipagem com InterfacesRecapitulação - Calculadora de Formas8Métodos Mágicos
Introdução aos Métodos Mágicos__toString e __debugInfo__get, __set, __isset, __unset__call e __callStatic__clone e Clonagem de Objetos__serialize e __unserializeRecapitulação - Coleção Personalizada11Sistema de Tipos e Tratamento de Erros
Declarações de TiposTipos NulosTipos de União e InterseçãoClasses de ExceçãoHierarquia de Exceções PersonalizadaTry, Catch, FinallyRecapitulação - Validador de Formulário14Projeto: Gerenciamento de Biblioteca
Visão Geral do ProjetoClasses de Livros e Usuários3Propriedades de Classes
Propriedades de Instância vs. EstáticasConstantes em ClassesMétodos e Propriedades EstáticosPropriedades Privadas e ProtegidasPropriedades Somente para Leitura (PHP 8.1)Recapitulação - Gerenciador de Contas Bancárias6Polimorfismo
Revisão da Sobrescrita de MétodosPolimorfismo via InterfacesIndicação de Tipos e Tipos UnionVinculação Estática TardiaRecapitulação - Processador de Pagamentos9Traits
Introdução a TraitsUsando Múltiplos TraitsResolução de Conflitos entre TraitsMétodos Abstratos em TraitsTraits vs. Herança12Padrões de Projeto – Parte 1
Introdução aos Padrões de ProjetoPadrão SingletonPadrão FactoryPadrão ObserverPadrão StrategyPratique por conta própria: Compilador de PHP online