Menu
Coddy logo textTech

Modello Adapter

Fa parte della sezione Programmazione orientata agli oggetti del percorso PHP di Coddy. Lezione 76 di 91.

Il pattern Adapter è un pattern strutturale che consente a oggetti con interfacce incompatibili di collaborare. Funge da ponte tra due interfacce, traducendo le chiamate da un formato all'altro.

Immagina di creare un'applicazione che elabora pagamenti e di dover integrare una libreria di pagamento di terze parti. La libreria funziona perfettamente, ma la sua interfaccia non corrisponde a ciò che il tuo codice si aspetta. Invece di riscrivere l'intera applicazione, crei un adattatore che fa da tramite tra i due.

<?php
// L'interfaccia che la tua applicazione si aspetta
interface PaymentProcessor {
    public function pay(float $amount): string;
}

// Libreria di terze parti con un'interfaccia diversa
class StripeAPI {
    public function createCharge(int $cents, string $currency): string {
        return "Charged {$cents} {$currency} via Stripe";
    }
}

L'adattatore implementa l'interfaccia prevista e usa internamente la classe di terze parti:

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

Output:

Charged 2999 USD via Stripe

L'adattatore converte i dollari in centesimi e chiama il metodo appropriato. Il codice della tua applicazione conosce solo PaymentProcessor, senza preoccuparsi dei requisiti specifici di Stripe. Se in seguito passi a un altro fornitore di servizi di pagamento, ti basta creare un nuovo adattatore senza modificare il codice esistente.

challenge icon

Sfida

Facile

Creiamo un sistema di conversione della temperatura usando l'Adapter Pattern. Hai un sensore di temperatura legacy che restituisce misurazioni in Fahrenheit, ma la tua moderna applicazione meteo si aspetta che tutte le temperature siano in Celsius. Invece di modificare uno dei due sistemi, creerai un adattatore che colmi il divario.

Organizzerai il codice in quattro file:

  • TemperatureSensor.php: definisci un'interfaccia TemperatureSensor che l'applicazione meteo si aspetta. Dovrebbe avere un metodo getTemperature(): float che restituisce la temperatura in Celsius.
  • LegacySensor.php: crea una classe LegacySensor che simula il vecchio hardware. Questa classe ha un'interfaccia diversa da quella richiesta dalla tua applicazione:
    • Accetta una misurazione in Fahrenheit nel costruttore (usa la promozione del costruttore)
    • Ha un metodo readFahrenheit(): float che restituisce il valore Fahrenheit memorizzato
  • LegacySensorAdapter.php: includi sia l'interfaccia TemperatureSensor sia la classe LegacySensor. Crea una classe LegacySensorAdapter che implementa TemperatureSensor e avvolge un LegacySensor. L'adattatore dovrebbe:
    • Accettare un LegacySensor nel costruttore
    • Implementare getTemperature() leggendo il valore Fahrenheit dal sensore legacy e convertendolo in Celsius usando la formula: (fahrenheit - 32) * 5 / 9
  • main.php: includi il file LegacySensorAdapter. Riceverai un input: una temperatura in Fahrenheit.

    Crea un LegacySensor con la temperatura di input, quindi avvolgilo in un LegacySensorAdapter. Chiama getTemperature() sull'adattatore e stampa il risultato arrotondato a due cifre decimali.

    Il formato di output deve essere: Temperature: [celsius]C

Questa sfida dimostra come l'Adapter Pattern ti permetta di integrare interfacce incompatibili senza modificare il codice esistente. La tua applicazione meteo lavora esclusivamente con l'interfaccia TemperatureSensor, senza sapere che le misurazioni effettive provengono da un sensore Fahrenheit legacy.

Provalo tu

<?php
require_once 'LegacySensorAdapter.php';

// Leggi l'input
$fahrenheit = floatval(trim(fgets(STDIN)));

// TODO: Crea un LegacySensor con la temperatura in input
// TODO: Incapsulalo in un LegacySensorAdapter
// TODO: Chiama getTemperature() sull'adapter
// TODO: Stampa il risultato arrotondato a due cifre decimali
// Formato di output: Temperature: [celsius]C

?>
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore PHP online