Menu
Coddy logo textTech

Pattern dell’Adattatore

Fa parte della sezione Programmazione orientata agli oggetti del percorso C# di Coddy. Lezione 57 di 70.

Il pattern Adapter è un pattern strutturale che consente a interfacce incompatibili di lavorare insieme. Agisce da ponte tra due classi, convertendo l’interfaccia di una classe in un’interfaccia che i client si aspettano. Immaginalo come un adattatore di corrente che ti permette di collegare un dispositivo europeo a una presa americana.

Questo schema è particolarmente utile quando vuoi usare una classe esistente, ma la sua interfaccia non corrisponde a ciò di cui ha bisogno il tuo codice. Invece di modificare la classe originale (che potresti non controllare), crei un adattatore che la racchiude:

// Classe esistente con un'interfaccia incompatibile
public class OldPrinter
{
    public void PrintMessage(string msg) => Console.WriteLine($"Old: {msg}");
}

// Interfaccia prevista dal tuo codice
public interface IPrinter
{
    void Print(string text);
}

// L'adattatore colma la differenza
public class PrinterAdapter : IPrinter
{
    private OldPrinter _oldPrinter;
    
    public PrinterAdapter(OldPrinter oldPrinter)
    {
        _oldPrinter = oldPrinter;
    }
    
    public void Print(string text)
    {
        _oldPrinter.PrintMessage(text);  // Delega alla vecchia interfaccia
    }
}

Ora il tuo codice può funzionare con la vecchia stampante tramite l’interfaccia prevista:

OldPrinter legacy = new OldPrinter();
IPrinter printer = new PrinterAdapter(legacy);

printer.Print("Hello");  // Old: Hello

Il pattern Adapter è prezioso quando integri librerie di terze parti o codice legacy nella tua applicazione. Il codice client interagisce con l’interfaccia IPrinter, senza sapere che dietro le quinte è una vecchia classe incompatibile a svolgere il lavoro effettivo.

challenge icon

Sfida

Facile

Creiamo un sistema di riproduzione multimediale usando il pattern Adapter. Hai una libreria audio esistente che riproduce file MP3, ma la tua applicazione ha bisogno di un'interfaccia unificata in grado di gestire diversi tipi di contenuti multimediali. Creerai un adapter per colmare questa lacuna, consentendo al tuo lettore multimediale moderno di funzionare senza problemi con la libreria audio legacy.

Organizzerai il codice in tre file:

  • LegacyAudio.cs: rappresenta una libreria esistente che non puoi modificare. Crea una classe LegacyAudioPlayer nello spazio dei nomi MediaSystem con un metodo PlayMp3(string filename) che restituisce la stringa "Playing MP3: {filename}". Questo è il tuo «adaptee», ovvero la classe con l'interfaccia incompatibile.
  • MediaAdapter.cs: crea l'interfaccia e l'adapter nello stesso spazio dei nomi. Definisci un'interfaccia IMediaPlayer con un metodo Play(string filename) che restituisce una stringa. Poi crea una classe MediaPlayerAdapter che implementa IMediaPlayer. Il tuo adapter deve racchiudere un'istanza di LegacyAudioPlayer (passata tramite il costruttore) e tradurre la chiamata a Play nella chiamata al metodo PlayMp3 del lettore legacy.
  • Program.cs: assembla il tutto creando il lettore legacy, racchiudendolo nel tuo adapter e usando l'adapter tramite l'interfaccia IMediaPlayer. Questo dimostra come il codice client possa lavorare con l'interfaccia moderna mentre l'adapter gestisce la comunicazione con il sistema legacy dietro le quinte.

Riceverai un input:

  • Il nome del file da riprodurre (ad es. song.mp3)

Crea un LegacyAudioPlayer, racchiudilo in un MediaPlayerAdapter, poi chiama Play sull'adapter usando l'interfaccia IMediaPlayer e stampa il risultato.

Ad esempio, se l'input è favorite_track.mp3, l'output dovrebbe essere:

Playing MP3: favorite_track.mp3

La bellezza di questo pattern è che il tuo codice principale interagisce solo con IMediaPlayer: non sa che a svolgere il lavoro effettivo è una libreria audio legacy. Se in seguito dovessi supportare una libreria legacy diversa, ti basterebbe creare un nuovo adapter senza modificare alcun codice client!

Provalo tu

using System;
using MediaSystem;

class Program
{
    public static void Main(string[] args)
    {
        // Leggi il nome del file inserito
        string filename = Console.ReadLine();
        
        // TODO: Crea un'istanza di LegacyAudioPlayer
        
        // TODO: Inseriscila in un MediaPlayerAdapter
        
        // TODO: Usa l'adapter tramite l'interfaccia IMediaPlayer
        // e stampa il risultato della chiamata a Play con il nome del file
    }
}
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 C# online