Pattern Adapter
Fa parte della sezione Programmazione orientata agli oggetti del percorso Java di Coddy. Lezione 71 di 87.
L'Adapter Pattern è un pattern strutturale che consente a interfacce incompatibili di funzionare insieme. Agisce da ponte tra due classi, convertendo l'interfaccia di una classe in un'interfaccia che il client si aspetta. Pensalo come a un adattatore di corrente che ti permette di collegare un dispositivo europeo a una presa americana.
Immagina di avere un'interfaccia MediaPlayer esistente che riproduce file audio, ma di dover integrare una libreria di terze parti che usa un'interfaccia completamente diversa per riprodurre video:
// Interfaccia esistente utilizzata dal tuo codice
interface MediaPlayer {
void play(String filename);
}
// Classe di terze parti con un'interfaccia incompatibile
class AdvancedVideoPlayer {
public void playVideo(String filename) {
System.out.println("Playing video: " + filename);
}
}L'adattatore avvolge la classe incompatibile e implementa l'interfaccia prevista, traducendo le chiamate tra le due:
class VideoPlayerAdapter implements MediaPlayer {
private AdvancedVideoPlayer videoPlayer;
public VideoPlayerAdapter() {
this.videoPlayer = new AdvancedVideoPlayer();
}
public void play(String filename) {
videoPlayer.playVideo(filename);
}
}Ora il tuo codice client può usare il lettore video tramite la familiare interfaccia MediaPlayer:
MediaPlayer player = new VideoPlayerAdapter();
player.play("movie.mp4"); // Output: Riproduzione video: movie.mp4Il Pattern Adapter è prezioso quando si integrano codice legacy o librerie di terze parti senza modificarne il codice sorgente. Il client non si accorge di lavorare con una classe adattata. Usa semplicemente l’interfaccia che conosce.
Sfida
FacileCreiamo un sistema di conversione della temperatura usando il Pattern Adapter! Hai un'applicazione meteo esistente che lavora con temperature in Celsius, ma devi integrare un sensore di temperatura legacy che fornisce letture solo in Fahrenheit. Invece di modificare uno dei due sistemi, creerai un adapter che colma il divario.
Organizzerai il codice in quattro file:
TemperatureProvider.java: Definisci l'interfaccia che si aspetta la tua applicazione meteo. Dovrebbe dichiarare un metodogetTemperatureCelsius()che restituisce un double che rappresenta la temperatura in Celsius.FahrenheitSensor.java: Rappresenta il sensore legacy con un'interfaccia incompatibile. Crea una classe con un campo double privato per la temperatura in Fahrenheit, impostato tramite il costruttore. Dovrebbe avere un metodoreadFahrenheit()che restituisce il valore Fahrenheit memorizzato.SensorAdapter.java: Crea l'adapter che rende il sensore Fahrenheit compatibile con la tua applicazione meteo. L'adapter dovrebbe implementareTemperatureProvidere racchiudere unFahrenheitSensor. Quando viene chiamatogetTemperatureCelsius(), dovrebbe leggere il valore dal sensore e convertirlo in Celsius usando la formula:(fahrenheit - 32) * 5 / 9.Main.java: Metti insieme tutti gli elementi! Riceverai un input: una lettura della temperatura in Fahrenheit (double).Crea un
FahrenheitSensorcon il valore di input. Poi crea unSensorAdapterche racchiuda questo sensore. Memorizza l'adapter in una variabile di tipoTemperatureProviderper dimostrare che la tua applicazione meteo può usarlo tramite l'interfaccia prevista.Stampa il risultato in questo formato:
Temperature: [celsius] Cdove celsius è formattato con una cifra decimale.
Riceverai un input: la temperatura in Fahrenheit (double).
Per esempio, con l'input 98.6, l'output sarà:
Temperature: 37.0 CNota come la tua classe Main lavori interamente con l'interfaccia TemperatureProvider. Non sa che la temperatura effettiva proviene da un sensore Fahrenheit adattato dietro le quinte. Questa è l'eleganza del Pattern Adapter!
Provalo tu
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
double fahrenheit = scanner.nextDouble();
// TODO: Crea un FahrenheitSensor con il valore di input
// TODO: Crea un SensorAdapter che incapsuli il sensore
// TODO: Memorizza l'adattatore in una variabile TemperatureProvider
// TODO: Ottieni la temperatura in Celsius e stampala
// Formato: "Temperature: [celsius] C" con una cifra decimale
// Suggerimento: usa String.format("%.1f", value) per la formattazione
}
}
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 a oggetti
File esterniIntroduzione alla programmazione a oggettiClassi e oggettiLa parola chiave thisMetodiCampi (attributi)Metodo costruttoreSovraccarico dei costruttoriRipasso - Calcolatrice semplice4Ereditarietà
Ereditarietà di base (extends)La parola chiave superSovrascrittura dei metodi (@Override)Concatenamento dei costruttoriLa classe ObjectEreditarietà singola e multilivelloPerché non esiste l'ereditarietà multipla delle classiRiepilogo: gerarchia dei dipendenti7Metodi speciali e classe Object
Metodo toString()equals() e hashCode()Metodo clone()compareTo() e ComparableInterfaccia ComparatorRiepilogo - Ordinamento personalizzato2Modificatori di accesso e incapsulamento
Panoramica dei livelli di accessoMetodi getter e setterNascondimento delle informazioniLa parola chiave finalRiepilogo - Gestore di conti bancari5Polimorfismo
Nozioni di base sull'overloading dei metodiOverride dei metodi (a runtime)Upcasting e downcastingL'operatore instanceofClassi e metodi astrattiRiepilogo - Calcolatore di forme8Concetti avanzati di OOP
Composizione vs ereditarietàAggregazione vs composizioneClassi interne, annidate e anonimeEnum e metodi degli EnumRecord (Java 16+)Classi sealed (Java 17+)11Modelli di progettazione Parte 1
Introduzione ai modelli di progettazionePattern SingletonPattern FactoryPattern BuilderPattern ObserverPattern Strategy3Proprietà di classe e membri statici
Variabili di istanza e staticheMetodi staticiBlocchi staticiCostanti (static final)Riepilogo - Contatore e utility6Interfacce e classi astratte
Introduzione alle interfacceImplementazione delle interfacceImplementazione di più interfacceMetodi default e static nelle interfacceClassi astratte e interfacce a confrontoInterfacce funzionaliRiepilogo: sistema di pagamento9Tipi generici
Introduzione ai tipi genericiClassi genericheMetodi genericiParametri di tipo con limitiCaratteri jolly (?, extends, super)Riepilogo - Contenitore generico12Modelli di progettazione – Parte 2
Pattern CommandPattern AdapterPattern DecoratorPattern Template MethodPattern StatePattern CompositePattern IteratorEsercitati da solo: Compilatore Java online