Patron Adaptateur
Fait partie de la section Programmation Orientée Objet du Journey Java de Coddy. Leçon 71 sur 87.
Le patron Adaptateur est un patron de conception structurel qui permet à des interfaces incompatibles de fonctionner ensemble. Il agit comme un pont entre deux classes, en convertissant l’interface d’une classe en une interface attendue par le client. Imaginez-le comme un adaptateur secteur qui vous permet de brancher un appareil européen sur une prise américaine.
Imagine que vous disposez d’une interface MediaPlayer existante qui lit des fichiers audio, mais que vous devez intégrer une bibliothèque tierce qui utilise une interface complètement différente pour lire des vidéos :
// Interface existante que votre code utilise
interface MediaPlayer {
void play(String filename);
}
// Classe tierce avec une interface incompatible
class AdvancedVideoPlayer {
public void playVideo(String filename) {
System.out.println("Playing video: " + filename);
}
}L’adaptateur encapsule la classe incompatible et implémente l’interface attendue, en traduisant les appels entre elles :
class VideoPlayerAdapter implements MediaPlayer {
private AdvancedVideoPlayer videoPlayer;
public VideoPlayerAdapter() {
this.videoPlayer = new AdvancedVideoPlayer();
}
public void play(String filename) {
videoPlayer.playVideo(filename);
}
}Désormais, votre code client peut utiliser le lecteur vidéo via l’interface familière MediaPlayer :
MediaPlayer player = new VideoPlayerAdapter();
player.play("movie.mp4"); // Sortie : Lecture de la vidéo : movie.mp4Le pattern Adapter est précieux lors de l’intégration de code existant ou de bibliothèques tierces sans modifier leur code source. Le client ignore qu’il travaille avec une classe adaptée. Il utilise simplement l’interface qu’il connaît.
Défi
FacileConstruisons un système de conversion de températures à l'aide du pattern Adapter ! Vous disposez d'une application météo existante qui fonctionne avec des températures en Celsius, mais vous devez intégrer un ancien capteur de température qui fournit uniquement des relevés en Fahrenheit. Au lieu de modifier l'un ou l'autre système, vous allez créer un adaptateur qui fera le lien entre eux.
Vous allez organiser votre code dans quatre fichiers :
TemperatureProvider.java: définissez l'interface attendue par votre application météo. Elle doit déclarer une méthodegetTemperatureCelsius()qui renvoie un double représentant la température en Celsius.FahrenheitSensor.java: cela représente l'ancien capteur avec une interface incompatible. Créez une classe avec un champ double privé pour la température en Fahrenheit, défini par le constructeur. Elle doit disposer d'une méthodereadFahrenheit()qui renvoie la valeur Fahrenheit enregistrée.SensorAdapter.java: créez l'adaptateur qui rend le capteur Fahrenheit compatible avec votre application météo. Votre adaptateur doit implémenterTemperatureProvideret encapsuler unFahrenheitSensor. LorsquegetTemperatureCelsius()est appelée, elle doit lire la valeur du capteur et la convertir en Celsius à l'aide de la formule :(fahrenheit - 32) * 5 / 9.Main.java: rassemblez tous les éléments ! Vous recevrez une entrée : une température en Fahrenheit (double).Créez un
FahrenheitSensoravec la valeur d'entrée. Créez ensuite unSensorAdapterqui encapsule ce capteur. Stockez l'adaptateur dans une variableTemperatureProviderafin de démontrer que votre application météo peut l'utiliser via l'interface attendue.Affichez le résultat dans ce format :
Temperature: [celsius] C, où celsius est formaté avec une décimale.
Vous recevrez une entrée : la température en Fahrenheit (double).
Par exemple, avec l'entrée 98.6, votre sortie serait :
Temperature: 37.0 CRemarquez que votre classe Main fonctionne entièrement avec l'interface TemperatureProvider. Elle ne sait pas que la température réelle provient d'un capteur Fahrenheit adapté en arrière-plan. Voilà toute l'élégance du pattern Adapter !
Essayez vous-même
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
double fahrenheit = scanner.nextDouble();
// TODO: Créez un FahrenheitSensor avec la valeur d'entrée
// TODO: Créez un SensorAdapter qui encapsule le capteur
// TODO: Stockez l'adaptateur dans une variable TemperatureProvider
// TODO: Obtenez la température en Celsius et affichez-la
// Format : "Temperature: [celsius] C" avec une décimale
// Astuce : Utilisez String.format("%.1f", value) pour le formatage
}
}
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Programmation Orientée Objet
1Fondamentaux de la POO
Fichiers externesIntroduction à la POOClasses vs ObjetsLe mot-clé thisMéthodesChamps (Attributs)Méthode constructeurSurcharge de constructeurRécapitulatif - Calculatrice simple4Héritage
Héritage de base (extends)Le mot-clé superRedéfinition de méthode (@Override)Chaînage de constructeursLa classe ObjectHéritage simple et multiniveauPourquoi pas d'héritage multiple de classesRécapitulatif - Hiérarchie des employés7Méthodes spéciales et classe Object
Méthode toString()equals() et hashCode()Méthode clone()compareTo() et ComparableInterface ComparatorRécapitulatif - Tri personnalisé2Modificateurs d'accès et Encapsulation
Aperçu des niveaux d'accèsMéthodes Getter et SetterMasquage d'informationsLe mot-clé finalRécapitulatif - Gestionnaire de compte bancaire5Polymorphisme
Bases de la surcharge de méthodesRedéfinition de méthodes (Run-Time)Upcasting et DowncastingL'opérateur instanceofClasses et méthodes abstraitesRécapitulatif - Calculateur de formes8Concepts avancés de la POO
Composition vs HéritageAgrégation vs CompositionClasses internes, imbriquées et anonymesEnums et méthodes d'EnumRecords (Java 16+)Classes scellées (Java 17+)11Patrons de conception, partie 1
Introduction aux patrons de conceptionPatron SingletonPatron FabriquePatron MonteurPatron ObservateurPatron Stratégie3Propriétés de classe et membres statiques
Variables d'instance vs variables statiquesMéthodes statiquesBlocs statiquesConstantes (static final)Récapitulatif - Compteur et utilitaire6Interfaces et Classes Abstraites
Introduction aux InterfacesImplémentation d'InterfacesImplémentation d'Interfaces MultiplesDefault et Static dans les InterfacesClasses Abstraites vs InterfacesInterfaces FonctionnellesRécapitulatif - Système de Paiement9La généricité
Introduction à la généricitéClasses génériquesMéthodes génériquesParamètres de type bornésWildcards (?, extends, super)Récapitulatif - Conteneur générique12Patrons de conception, partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Template MethodPatron ÉtatPatron CompositePatron ItérateurEntraînez-vous par vous-même : Compilateur Java en ligne