Menu
Coddy logo textTech

Patrón Adapter

Parte de la sección Programación Orientada a Objetos del Journey de PHP de Coddy. Lección 76 de 91.

El patrón Adaptador es un patrón de diseño estructural que permite que objetos con interfaces incompatibles trabajen juntos. Actúa como un puente entre dos interfaces, traduciendo las llamadas de un formato a otro.

Imagina que estás creando una aplicación que procesa pagos y necesitas integrar una biblioteca de pagos de terceros. La biblioteca funciona perfectamente, pero su interfaz no coincide con lo que espera tu código. En lugar de reescribir toda tu aplicación, creas un adaptador que traduce entre ambos.

<?php
// La interfaz que espera tu aplicación
interface PaymentProcessor {
    public function pay(float $amount): string;
}

// Biblioteca de terceros con una interfaz diferente
class StripeAPI {
    public function createCharge(int $cents, string $currency): string {
        return "Charged {$cents} {$currency} via Stripe";
    }
}

El adaptador implementa la interfaz esperada mientras utiliza internamente la clase de terceros:

<?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);

Salida:

Charged 2999 USD via Stripe

El adaptador convierte los dólares en centavos y llama al método correspondiente. El código de tu aplicación solo conoce PaymentProcessor, sin preocuparse por los requisitos específicos de Stripe. Si más adelante cambias a otro proveedor de pagos, simplemente creas un adaptador nuevo sin modificar el código existente.

challenge icon

Desafío

Fácil

Construyamos un sistema de conversión de temperatura utilizando el patrón Adapter. Tienes un sensor de temperatura heredado que proporciona lecturas en Fahrenheit, pero tu aplicación meteorológica moderna espera todas las temperaturas en Celsius. En lugar de modificar cualquiera de los dos sistemas, crearás un adaptador que conecte ambos.

Organizarás tu código en cuatro archivos:

  • TemperatureSensor.php: Define una interfaz TemperatureSensor que tu aplicación meteorológica espera. Debe tener un método getTemperature(): float que devuelva la temperatura en Celsius.
  • LegacySensor.php: Crea una clase LegacySensor que simule el hardware antiguo. Esta clase tiene una interfaz diferente de la que necesita tu aplicación:
    • Recibe una lectura en Fahrenheit en su constructor (utiliza la promoción de constructor)
    • Tiene un método readFahrenheit(): float que devuelve el valor Fahrenheit almacenado
  • LegacySensorAdapter.php: Incluye tanto la interfaz TemperatureSensor como la clase LegacySensor. Crea una clase LegacySensorAdapter que implemente TemperatureSensor y envuelva un LegacySensor. Tu adaptador debe:
    • Aceptar un LegacySensor en su constructor
    • Implementar getTemperature() leyendo el valor Fahrenheit del sensor heredado y convirtiéndolo a Celsius mediante la fórmula: (fahrenheit - 32) * 5 / 9
  • main.php: Incluye el archivo LegacySensorAdapter. Recibirás una entrada: una temperatura en Fahrenheit.

    Crea un LegacySensor con la temperatura de entrada y, después, envuélvelo en un LegacySensorAdapter. Llama a getTemperature() en el adaptador e imprime el resultado redondeado a dos decimales.

    El formato de salida debe ser: Temperature: [celsius]C

Este desafío demuestra cómo el patrón Adapter permite integrar interfaces incompatibles sin modificar el código existente. Tu aplicación meteorológica trabaja exclusivamente con la interfaz TemperatureSensor, sin saber que las lecturas reales provienen de un sensor Fahrenheit heredado.

Pruébalo tú mismo

<?php
require_once 'LegacySensorAdapter.php';

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

// TODO: Crea un LegacySensor con la temperatura de entrada
// TODO: Envuélvelo en un LegacySensorAdapter
// TODO: Llama a getTemperature() en el adaptador
// TODO: Imprime el resultado redondeado a dos decimales
// Formato de salida: Temperature: [celsius]C

?>
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación Orientada a Objetos

Practica por tu cuenta: Compilador de PHP online