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: HelloIl 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.
Sfida
FacileCreiamo 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 classeLegacyAudioPlayernello spazio dei nomiMediaSystemcon un metodoPlayMp3(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'interfacciaIMediaPlayercon un metodoPlay(string filename)che restituisce una stringa. Poi crea una classeMediaPlayerAdapterche implementaIMediaPlayer. Il tuo adapter deve racchiudere un'istanza diLegacyAudioPlayer(passata tramite il costruttore) e tradurre la chiamata aPlaynella chiamata al metodoPlayMp3del lettore legacy.Program.cs: assembla il tutto creando il lettore legacy, racchiudendolo nel tuo adapter e usando l'adapter tramite l'interfacciaIMediaPlayer. 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.mp3La 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
}
}
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
1Fondamenti della programmazione orientata agli oggetti
File esterniNamespace e direttiveIntroduzione a classi e oggettiLa parola chiave "this"Metodi e parametriCampi e proprietàCostruttoriInizializzatori di oggettiRiepilogo - Calcolatrice semplice4Ereditarietà
Sintassi di base dell'ereditarietà (:)La parola chiave 'base'Parole chiave virtual e overrideClassi sealedLa classe base 'object'Riepilogo - Gerarchia dei dipendenti7Funzionalità avanzate
Sovraccarico degli operatoriIndicizzatori (this[])Override di ToString()Metodi di estensioneRiepilogo - Lista personalizzata10Pattern di progettazione Parte 1
Introduzione ai pattern di progettazioneSingleton thread-safePattern FactoryPattern Observer (eventi)Pattern Strategy2Proprietà e membri statici
Proprietà implementate automaticamenteProprietà di sola lettura e di sola scritturaCampi e metodi staticiClassi staticheMembri con corpo di espressione5Polimorfismo e interfacce
Polimorfismo a compile time e runtimeInterfaccia o classe astrattaInterfacce multipleInterfacce espliciteUpcasting e downcastingRipasso: calcolatore di forme8Concetti avanzati di programmazione a oggetti
Composizione invece dell'ereditarietàTipi generici (classi e metodi)Delegati ed eventiAttributi e reflectionIDisposable e istruzione usingNozioni di base sull'iniezione delle dipendenze11Pattern di progettazione, parte 2
Pattern del ComandoPattern dell’AdattatorePattern del DecoratorePattern Template MethodPattern dello StatoPattern Composito3Architettura delle classi
Dati di istanza vs staticiParole chiave 'readonly' e 'const'Campi di supportoRiepilogo - Gestore di conti bancari6Incapsulamento
Modificatori di accessoProprietà per l'incapsulamentoImplementazione dell'occultamento dei datiModelli di immutabilitàRiepilogo - Registri degli studentiEsercitati da solo: Compilatore C# online