Patron Adaptateur
Fait partie de la section Programmation Orientée Objet du Journey Dart de Coddy. Leçon 95 sur 110.
Le pattern Adapter permet à des interfaces incompatibles de fonctionner ensemble. Il agit comme un pont entre deux classes qui ne pourraient autrement pas collaborer, en enveloppant une classe existante avec une nouvelle interface attendue par les clients. Cela est particulièrement utile lors de l’intégration de bibliothèques tierces ou de code ancien dans votre application.
Imagine que vous avez un système qui fonctionne avec des données JSON, mais que vous devez intégrer un composant qui produit uniquement du XML. Au lieu de modifier l’une ou l’autre classe, vous créez un adaptateur qui assure la traduction entre elles :
// Interface existante attendue par votre système
abstract class JsonData {
String getJson();
}
// Classe legacy avec une interface incompatible
class XmlService {
String getXml() {
return '<data><name>John</name></data>';
}
}
// L'adaptateur rend XmlService compatible avec JsonData
class XmlToJsonAdapter implements JsonData {
final XmlService _xmlService;
XmlToJsonAdapter(this._xmlService);
@override
String getJson() {
String xml = _xmlService.getXml();
// Convertir XML en JSON (simplifié)
return '{"name": "John"}';
}
}
void main() {
var xmlService = XmlService();
var adapter = XmlToJsonAdapter(xmlService);
print(adapter.getJson()); // {"name": "John"}
}XmlToJsonAdapter encapsule XmlService et implémente l’interface JsonData. Le code client utilise l’interface familière JsonData sans savoir que les données provenaient à l’origine d’une source XML. L’adaptateur gère toute la traduction en interne.
Utilisez le modèle Adaptateur lorsque vous souhaitez utiliser une classe existante, mais que son interface ne correspond pas à vos besoins, ou lorsque vous devez créer une classe réutilisable qui collabore avec des classes ayant des interfaces incompatibles.
Défi
FacileConstruisons un système d’adaptateur pour lecteur multimédia ! Imagine que tu disposes d’un système audio moderne qui attend de toutes les sources multimédias qu’elles fournissent l’audio via une interface standard, mais que tu dois intégrer un ancien lecteur de disques vinyles qui produit le son d’une manière complètement différente.
Tu vas créer deux fichiers pour organiser l’implémentation de ton patron adaptateur :
media_adapter.dart: ce fichier contient tes classes d’interface et d’adaptateur. Définis une classe abstraiteAudioSourceattendue par ton système moderne : elle doit posséder une méthodeString playAudio()qui renvoie la sortie audio sous forme de chaîne. Crée ensuite une classeVinylPlayerreprésentant l’équipement existant : elle possède un champtrackNameet une méthodeString spinRecord()qui renvoie*crackle* Playing vinyl: [trackName] *crackle*. Enfin, construis unVinylAdapterqui implémenteAudioSourceet encapsule unVinylPlayer. La méthodeplayAudio()de l’adaptateur doit appeler la méthodespinRecord()du lecteur vinyle et renvoyer le résultat, faisant ainsi le lien entre les interfaces incompatibles.main.dart: importe ton fichier d’adaptateur multimédia et montre comment l’adaptateur permet à l’ancien lecteur vinyle de fonctionner avec du code qui attend l’interface moderneAudioSource. Crée unVinylPlayeravec le nom de pisteBohemian Rhapsody. Crée ensuite unVinylAdapterqui encapsule ce lecteur vinyle. Stocke l’adaptateur dans une variable de typeAudioSourcepour prouver qu’il respecte l’interface attendue. AppelleplayAudio()sur ta source audio et affiche le résultat.
La beauté de ce patron réside dans le fait que ton code principal fonctionne avec l’interface standard AudioSource : il n’a pas besoin de savoir qu’en coulisses, un ancien lecteur vinyle effectue réellement le travail !
Sortie attendue :
*crackle* Playing vinyl: Bohemian Rhapsody *crackle*Essayez vous-même
import 'media_adapter.dart';
void main() {
// TODO: Créez un VinylPlayer avec le nom de piste "Bohemian Rhapsody"
// TODO: Créez un VinylAdapter qui enveloppe le vinyl player
// TODO: Stockez l'adaptateur dans une variable de type AudioSource
// TODO: Appelez playAudio() sur votre source audio et affichez le résultat
}
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 externesBibliothèques et importsIntroduction à la POOClasses vs objetsLe mot-clé thisMéthodesVariables d’instanceBases des constructeursRécapitulatif - Calculatrice simple4Sécurité face aux valeurs nulles
Introduction à la sécurité face aux valeurs nullesNullable vs Non-NullableLes opérateurs ? et !Mot-clé Late et sécurité face aux valeurs nullesOpérateurs sensibles à nullSécurité face aux valeurs nulles dans les classesRécapitulatif – Système de profil utilisateur7Classes abstraites et interfaces
Classes abstraitesMéthodes abstraitesInterfaces en DartInterfaces implicitesImplémenter ou étendreInterfaces multiplesRécapitulatif - Calculateur de formes10Collections et génériques
Vue d’ensemble des List, Set et MapCollections à typage sûrClasses génériquesMéthodes génériquesContraintes génériquesIterable et IteratorRécapitulatif – stockage générique2Constructeurs en Dart
Constructeur par défautConstructeurs nommésListes d'initialisationConstructeurs constantsConstructeurs factoryConstructeurs redirigésRécapitulatif - Constructeur de formes5Encapsulation
Membres publics vs privésLa convention du préfixe _Confidentialité au niveau de la bibliothèqueApprofondissement des getters et settersMasquage de l’informationRécapitulatif - Fiches des étudiants8Mixins
Introduction aux MixinsCréer des MixinsUtiliser plusieurs MixinsMot-clé on dans les MixinsMixin ou héritageMixin ou interfaceRécapitulatif - Système animal11Méthodes spéciales
Redéfinition de toString()Redéfinition de hashCode et ==Interface ComparableMéthode call()Redéfinition de noSuchMethodRécapitulatif - Collection personnalisée14Patrons de conception, partie 1
Introduction aux patrons de conceptionPatron SingletonPatron FactoryPatron ObserverPatron Strategy3Propriétés des classes
Membres d’instance et statiquesChamps Final et ConstVariables différéesMéthodes et champs statiquesAccesseurs et mutateursRécapitulatif - Gestionnaire de compte bancaire6Héritage
Héritage de baseLe mot-clé superRedéfinition de méthodeL’annotation @overrideLe mot-clé de classe finalConstructeurs et héritageRécapitulatif – Hiérarchie des employés9Polymorphisme
Bases du polymorphismePolymorphisme via les interfacesVérification des types à l’exécutionLes opérateurs is et asMot-clé covariantRécapitulatif - Processeur de paiements12POO asynchrone
Futures et async/awaitNotions de base des StreamsContrôleurs de StreamsConstructeurs asynchronesAsynchrone dans les méthodes de classeRécapitulatif - récupérateur de données15Patrons de conception – Partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Méthode modèlePatron ÉtatPatron CompositePatron DépôtEntraînez-vous par vous-même : Compilateur Dart en ligne