Aide-mémoire, Head First Design Patterns, chapitre 7

Adapter et Facade

Ces deux patterns enveloppent des objets qui existent déjà. Adapter traduit une interface étrangère vers celle que le code attend. Facade cache plusieurs objets derrière une méthode simple.

Adapter : « Convertir l'interface d'une classe en une autre interface, conforme à l'attente du client. » Facade : « Fournir une interface unifiée à l'ensemble des interfaces d'un sous-système. » Gamma, Helm, Johnson et Vlissides, Design Patterns, 1994

Adapter et Facade dans une boutique En haut, Commande utilise l'interface ModeLivraison. ModeColisRapide implémente cette interface et traduit le JSON de l'API ColisRapide, dont les champs price_cents et delivery_days deviennent frais() et delaiJours(). En bas, un contrôleur appelle Caisse.passerCommande(), qui appelle à son tour Panier, Paiement, Stock et Courriel. Adapter, traduire Commande utilise Le transporteurparle son propre JSON. «interface» ModeLivraison Le contratde Commande. ModeColisRapide price_cents → frais() delivery_days → delaiJours() ColisRapide price_cents: 590 delivery_days: 2 L'adaptateur vérifie le JSON,puis le traduit pour Commande. Facade, simplifier Contrôleur POST /commande Caisse passerCommande() Panier Paiement Stock Courriel Une méthode cache quatre objets.Le contrôleur ne connaît que Caisse.

Adapter, traduire

La cible, ModeLivraison
Le contrat que Commande attend déjà.
Le service adapté, ColisRapide
Une API externe qui répond { "price_cents": 590, "delivery_days": 2 }. Ses noms ne sont pas ceux de l'application.
L'adaptateur, ModeColisRapide
Il vérifie la réponse, refuse un devis invalide avec une erreur, puis expose frais() et delaiJours().

Facade, simplifier

Caisse.passerCommande() lit le panier, débite le paiement, réserve le stock et envoie le courriel de confirmation. Le contrôleur appelle une méthode au lieu de coordonner quatre objets. Les objets cachés restent accessibles au code qui en a besoin.

Trois enveloppes, trois intentions

PatternInterface présentée au clientIntentionExemple
DecoratorLa même que l'objet entouréAjouter un comportementEmballageCadeau
AdapterCelle que le client attendTraduireModeColisRapide
FacadeUne interface nouvelle et plus simpleSimplifierCaisse

Le reconnaître

Adapter répond à des noms étrangers qui se répandent dans le code, comme price_cents ou delivery_days, ou à une même conversion répétée à chaque appel.

Facade répond à un contrôleur qui enchaîne plusieurs services dans un ordre précis, quand ce même enchaînement se retrouve copié ailleurs.

Le principe du chapitre

« Ne parlez qu'à vos amis immédiats. » Le livre appelle ce principe la connaissance minimale. Le contrôleur parle à Caisse, et Caisse parle au paiement, au stock et au courriel. Le contrôleur n'a pas à connaître leurs méthodes.

Dans le code web

Après un fetch, une fonction qui vérifie le JSON et renvoie un objet aux noms de l'application est un adaptateur. Une bibliothèque de validation comme Zod peut faire la vérification, et l'adaptateur garde la traduction.

Un module commandes.ts qui expose passerCommande aux routes d'une API est une façade. Les SDK de paiement en sont une aussi, puisqu'ils cachent les requêtes HTTP derrière quelques méthodes.

Le piège

Un adaptateur qui renvoie zéro quand la réponse est invalide transforme une panne en livraison gratuite. Il doit lever une erreur.

Une façade qui accumule toutes les opérations de l'application devient une classe géante. Elle reste utile tant qu'elle sert un usage précis.

À vous

Le transporteur renomme delivery_days en eta_days. Quels fichiers de l'application changent ?

Voir la réponse

Seulement l'adaptateur ModeColisRapide. Commande et le reste du code ne connaissent que ModeLivraison, donc le changement ne les atteint pas.