L’hexagone : mettre le domaine au centre, la technique en périphérie
Département de Mathématiques et Informatique, Faculté des Sciences et Techniques, Université Cheikh Anta Diop de Dakar
Contenu
Le Lab 1 a rangé la maison : couches propres, responsabilités séparées. Cette séance s’attaque au problème qui reste : le métier dépend toujours de la technique. Nous allons inverser cette dépendance — ports & adaptateurs, l’architecture dite hexagonale — et en apporter la preuve par le swap : remplacer la base de données par une simple Map, sans toucher une ligne du domaine.
L’acquis du Lab 1
Trois couches, des dépendances à sens unique, zéro SQL hors des repositories, les quartiers de Dakar à une seule adresse. Le God controller est mort : chaque responsabilité a une maison.
L’exigence nouvelle
La direction de SénResto exige que les règles métier — frais, transitions de statut, calcul d’ETA — soient testées à chaque commit. Les tests d’intégration (Spring + BDD + HTTP) prennent plusieurs secondes chacun : trop lents. Il faut des tests unitaires du métier. Essayez d’en écrire un sur CommandeService… vous n’y arriverez pas proprement.
Suivez les flèches de dépendance de CommandeService :
CommandeService \(\to\) CommandeRepository \(\to\) JdbcTemplate \(\to\) BDD
JdbcTemplate ; pour le JdbcTemplate, une base qui tourne.À retenir
Le problème n’est plus le désordre (Lab 1 l’a réglé) : c’est le sens des flèches. Tant que le métier pointe vers la technique, la technique dicte ses conditions au métier.
Définition
Principe d’inversion de dépendances (DIP) : le code de haut niveau (le métier) ne doit pas dépendre du code de bas niveau (la technique). Les deux doivent dépendre d’abstractions — des interfaces. Et surtout : ces interfaces sont définies par le métier, selon ses besoins.
Qui possède l’interface ?
Une interface ne suffit pas à inverser quoi que ce soit : si CommandeRepository définit lui-même son interface dans le paquetage repository, le domaine qui l’importe dépend toujours de la persistance. L’inversion se joue sur la propriété : l’interface habite chez le domaine, écrite dans son vocabulaire.
CommandesPort chez lui.À retenir
Inverser une dépendance, c’est déplacer la propriété du contrat : le métier ne demande plus la permission à la technique — il publie ses exigences, la technique s’y plie.
Définition (Alistair Cockburn, 2005)
L’architecture hexagonale (ports & adaptateurs) place le domaine au centre, entouré de ports — les interfaces qu’il définit. Les adaptateurs traduisent le monde extérieur vers les ports ou les implémentent. Règle unique : toutes les dépendances pointent vers le centre.
| Port entrant | Port sortant | |
|---|---|---|
| Qui l’appelle ? | le monde extérieur (REST, plus tard : messages) | le domaine |
| Qui l’implémente ? | le domaine | un adaptateur technique (JDBC, SMS…) |
| Chez SénResto | « créer une commande, la confirmer… » | « sauvegarder, chercher un livreur, notifier » |
Le test du vocabulaire
Lisez un port à voix haute : s’il parle de SELECT, de JSON ou de HTTP, il est mal placé. CommandesPort.sauvegarder(commande) — du métier. executerRequete(sql) — de la technique déguisée.
Le domaine écrit son besoin, dans son vocabulaire, chez lui :
class AdaptateurLivreursJdbc implements LivreursPort — trois méthodes déjà écrites, seule l’appartenance change.À retenir
Au Lab 2, vous n’écrirez presque pas de code nouveau : vous déplacerez la propriété du code existant. C’est un refactoring de frontières, pas une réécriture.
L’adaptateur in-memory — une Map — implémente les mêmes ports. Le test unitaire devient trivial :
@Test
void lesFraisDeLivraisonSuiventLeQuartier() {
var domaine = new CommandeMetier(new CommandesEnMemoire(),
new RestaurantsEnMemoire(), new LivreursEnMemoire(),
new NotificationsEnMemoire());
var commande = domaine.creer(new CommandeRequete(
"Awa Ba", "770000000", "Ouakam", 1L, 2));
assertEquals(2500 * 2 + 1500, commande.montantTotal()); // verdict : ~2 s
}À retenir — le réflexe de l’architecte
Toujours la même question : qu’est-ce que j’achète, avec quoi je le paie ? Votre ADR no2 devra répondre pour SénResto — pas en général.
Point de départ : votre lab1-final. Le comportement de l’API ne change pas d’un octet — les 4 tests d’intégration restent les juges de paix.
| Rôle | Pilotage au Lab 2 |
|---|---|
| Le Doyen | branches, merges, tags — et l’ADR avec l’Architecte du jour |
| L’Huissier | le domaine des commandes : CommandeMetier + ports sortants |
| Le Rédacteur | l’adaptateur REST (controllers) branché sur les ports entrants |
| Le Notaire | les adaptateurs JDBC : implements des ports, SQL inchangé |
| L’Appariteur | les adaptateurs in-memory + les nouveaux tests unitaires du domaine |
Le livrable individuel de la séance
L’Architecte du jour signe l’ADR no2 : « Pourquoi inverser les dépendances ? » — une page, deux alternatives sérieuses, deux conséquences négatives assumées.
À retenir
La question qui ouvre la séance 3
Votre hexagone protège le métier… mais tout SénResto vit dans un seul hexagone : Catalogue, Commandes, Paiement, Livraison s’y mélangent. Où sont les frontières entre les métiers ? Réponse au Lab 3 : le monolithe modulaire.