BT

Diffuser les Connaissances et l'Innovation dans le Développement Logiciel d'Entreprise

Contribuez

Sujets

Sélectionner votre région

Accueil InfoQ Actualités Live Code pour pratiquer l'Architecture Hexagonale

Live Code pour pratiquer l'Architecture Hexagonale

La tendance du Craftsmanship des dernières années met en lumière le recours régulier à certains patterns. Le "Gang des quatre" les a rendus célèbres, à défaut d'une utilisation systématique. Ces patterns ne sont pas les seuls, et le Docteur Alistair Cockburn, signataire du manifeste Agile, en propose un complémentaire avec l'architecture hexagonale. Tout intéressant qu'il est, son usage semble encore plus délicat que les premiers patterns, et son utilisation dans la vraie vie paraît parfois compliquée.

Pour en présenter les modalités d'implémentation, Alistair Cockburn, Thomas Pierrain et Romeu Moura présenteront une session de live coding sur l'architecture hexagonale le 20 juin prochain. InfoQ FR a eu la chance d'échanger avec Thomas Pierrain autour de l'événement, du pattern, de son intérêt, ainsi que de la manière de l'implémenter.

 

InfoQ FR : Bonjour Thomas. Pourrais-tu nous rappeler ce qu'est "l'architecture hexagonale" ?

Thomas : L'Architecture Hexagonale est un pattern d'architecture qui permet de bien séparer le code métier du code plus "technique" afin d'éviter ce qu'on appelle le big ball of mud (ou code spaghetti) que l'on retrouve dans 80% des applications dîtes legacy.

L'intention initiale d'Alistair était d'éviter que la logique métier d'une application ne s'infiltre dans la partie "interface graphique", rendant ainsi le système beaucoup plus compliqué à comprendre, tester et à maintenir. Il voulait donc trouver un moyen de la contenir, tout en acceptant les nombreuses demandes de changement et de connectivité avec l'extérieur que lui formulaient ses clients.

Au lieu de systématiser l'usage de nombreuses couches (pattern d'architecture Layers) comme on le rencontre trop souvent, on ne va ici considérer que 2 zones principales pour notre application : le dedans et le dehors. Le "dedans" ? C'est là où l'on va retrouver le code du domaine (i.e. le code métier). Le "dehors" ? C'est là où l'on va mettre le code technique que j'appelle moi le code d'infra(structure) : stack HTTP ou middleware préférés, drivers de base de données, appels à d'autres services externes, Data Transfert Objects (DTOs), etc.

Deux zones distinctes donc, et un sens unique pour les dépendances de projets/librairies : toujours de l'extérieur vers l'intérieur. En d'autres termes, seul le code d'infrastructure a le droit de dépendre et d'utiliser le code du domaine. Le code métier lui doit être complètement autonome et n'avoir aucune dépendance technique. Pour entrer et sortir de cette zone purement métier, on passe donc par des petits passages balisés : ce qu'Alistair Cockburn appelle des "ports" et des "adapters" qui se combinent avec le principe d'inversion de dépendance (DIP, le fameux "D" de l'acronyme SOLID) qu'Alistair préfère désormais appeller Configurable Dependencies (terme suggéré par Gerard Meszaros) pour éviter les modèles mentaux négatifs (du genre fait l'inverse de ce que tu as l'habitude de faire). C'est grâce au DIP que la logique métier peut aller récupérer des infos dans une base de données derrière le code d'infra au runtime, ou auprès d'un service extérieur.

Pour moi, c'est un des premiers pièges dans l'implémentation de ce pattern : savoir ce qu'est un Port et ce qu'est un Adapter ;-) je me rappelle encore des discussions sans fin entre collègues il y a quelques années, pour définir les uns et les autres). J'ai moi-même été longtemps à côté de la plaque sur leur interprétation avant d'en reparler tout récemment avec Alistair.

Un "port" représente une intention, c'est donc pour cela qu'on le représente en général sous la forme d'une interfaces en Java ou en C# (du genre IReserveTrainSeats ou IProvideClientPreferences). Un port peut avoir plusieurs "verbes"/méthodes mais ceux-ci doivent rester cohésifs, c'est-à-dire partager la même intention métier (ex : les modalités pour réserver un billet de train). Un "adapteur", c'est plus largement tout ce qui est nécessaire pour faire le lien entre ces 2 mondes (infra et domaine). Un adapteur va donc être en général la combinaison d'une stack technologique et de notre code qui fait l'adaptation des données d'un modèle à l'autre (vice et versa).

Après plusieurs années de mise en œuvre du pattern, les gens se sont rendus compte des nombreux autres atouts de celui-ci. Par exemple :

  • Testabilité : en forçant à passer par des ports (i.e. des interfaces en java ou C#) à chaque fois qu'on veut entrer/sortir de la logique métier, on aboutit à une situation où il est aisé de "mock-er" ou "stub-er" les dépendances externes (d'infrastructure). Cela simplifie grandement l'écriture de nos tests d'acceptance (ou tests "boîte noire", c'est à dire sans l'utilisation de vrais middleware mais en testant les couches d'adaptations Infra (e.g. JSON <-> Domaine par exemple). C'est également pour cela que certains appellent ce pattern la "Testable Architecture".

  • Time to market : en limitant l'impact de la connectivité avec un nouveau système à la périphérie de notre application (c.ad. la zone de l'infra), on gagne le droit d'avoir moins de changements à faire dans notre code pour intégrer une nouvelle technologie. C'est pour cela que Cyrille Martraire et moi-même avions parlé de "même pas mal architecture" il y a quelques années maintenant (repris en Université à DEVOXX FR). Vous voulez rajouter un nouveau canal de communication sur le projet ? Un nouveau fournisseur de données ? Vas-y envoie : même pas mal ! (c'est tellement simple à rajouter)

  • Domain-driven : plutôt que de perdre notre temps à choisir notre technologie de base de données dès le début d'un projet (c'est-à-dire au moment où on a le moins d'information sur ce qu'il faut faire et par extension, sur ce dont on va avoir besoin), l'architecture Hexagonale nous permet de nous concentrer facilement sur le problème du Domaine à résoudre et de déférer ainsi nos choix d'architecture de la partie infra à un meilleur moment (base de données, middlewares, etc.). On voyage léger dès le départ (avec des stubs ou des implémentations fichiers pour nos bases de données) avant de consolider la partie Infrastructure (qui doit être un moyen, pas une fin pour le métier).

  • Pérénité : de l'application et de la logique métier surtout, qui évolue en général moins rapidement que les effets de mode dans les technologies ou frameworks (et je ne parle même pas ici de la cadence hebdomadaire et infernale de ce qui est swag ou pas en JS ;-). En découplant clairement les 2, on permet ainsi de rafraichir la partie technologique sans avoir à prendre de risque sur la partie métier qui peut rester indemne. On peut aussi laisser les tout jeune développeurs faire leurs armes (c'est-à-dire faire leurs propre frameworks ou céder aux effets de mode) sur la partie Infra sans mettre le code et la valeur métier en péril. C'est très pratique !

InfoQ FR : Concrètement, quels sont les cas d'usage d'un tel pattern ?

Thomas : Une fois qu'on a compris et codé son initialisation en 3 temps (le plus dur), ce style d'architecture est vraiment super simple à mettre en œuvre sur tout type de projet, mais côté back-end/serveurs plutôt (pour vos services par exemple). Certaines personnes ont tendance à dire que pour un micro-service ce n'est pas nécessaire car on n'aura qu'un nombre limité de technologies associées ou de façons d'exposer le service. Ce que je constate, c'est que tous les monolithes ont d'abord été des micro services (même si on ne les appelait pas ainsi) avant de devenir macros, puis obèses. Puisque cela ne coûte pas plus cher de mettre en place ces "barbelés" et ces passerelles autours du code métier dès le départ, autant commencer avec ce style d'architecture qui nous rendra très rapidement des services par la suite. Mais il faut souvent avoir déjà souffert sur du legacy pour s'en rendre compte et apprécier la valeur.

InfoQ FR : Tu as montré un cas d'usage de l'architecture hexagonale durant l'Après-Midi du DDD. Qu'allez-vous montrer durant la session de live code ?

Thomas : Oui, durant notre Après-midi du DDD (une formule avec plus de 3 heures de live-coding sur du legacy en compagnie d'un expert métier), nous voulions montrer que le DDD et l'architecture hexagonale n'étaient pas réservés aux projets qui commencent (greenfield). Le code legacy utilisé étant un peu tordu, faire émerger des ports et des adaptateurs a nécessité de bouger certaines responsabilités avant de les déplacer vers la zone du code d'infra. Du coup, le risque pour ceux qui découvraient l'architecture hexagonale en live, était d'associer la complexité de ce gros chantier de refactoring avec le pattern.

Cette fois-ci, on partira from scratch pour montrer qu'en 3-4 lignes de code on a déjà un hexagone, des ports et des adaptateurs. Le live-coding avec Alistair sera donc plus que jamais didactique. On veut économiser cette phase d'apprentissage et de tâtonnement de la 1ère implémentation à ceux qui auraient envie d'essayer le pattern. Voire de tordre le cou à certains messages véhiculés par Alistair dans son papier initial ("suspense" ... ;-)).

Et puis comme on veut essayer d'y mettre un peu de fun, on va essayer de proposer pleins de variantes de ports et d'adaptateurs possibles, en imaginant laisser le public choisir en live leur ordre d'implémentation.

InfoQ FR : Si dans mon code, qu'il soit greenfield ou legacy, je veux implémenter une architecture hexagonale, par où dois-je commencer ?

Thomas : Le domaine ! C'est à dire quel problème j'ai à résoudre ? Quels sont mes utilisateurs, leurs usages et comment je vais exposer ce service à ceux-ci.

Cela revient à itérer très rapidement au début sur la ou les APIs que notre hexagone (métier) va exposer pour ces utilisateurs, quitte à leur renvoyer des valeurs en dur ou "stub-ées" au début. Car l'objectif pour nous est d'avoir du feedback end-user et le plus rapidement possible. Pour ma part, je combine en général une approche "outside-in" du TDD (la double boucle : test d'acceptance - tests unitaires et en considérant mon système à venir comme une boîte noire avec des comportements que je fais émerger à travers mes tests d'acceptance) avec une posture "Carpaccio" qui me pousse à délivrer très régulièrement des petits incréments de valeur pour le métier (pas pour l'IT). Elephant Carpaccio ? Tiens, encore un truc que j'ai emprunté à Alistair durant toutes ces années ;-)

InfoQ FR : L'événement est porté par plusieurs Meetup parisiens. Pourrais-tu nous raconter les détails de cette organisation ?

Thomas : Oui, tout est parti d'un tweet d'Alistair il y a quelques semaines où il demandait si quelqu'un serait intéressé par une session où il expliquerait son pattern accompagné d'un développeur qui live-coderait avec lui. Faisant la promotion de ce pattern depuis plus de 5 ans maintenant auprès de mes collègues, sur mon blog et dans différentes conférences, j'ai tout de suite répondu oui. En fait avec du recul, je pense qu'il demandait plutôt à ses followers "qui serait intéressé pour assister à un tel talk ?" et pas forcément : "qui serait intéressé pour live-coder à mes côtés ?" ;-) Mais bon, l'idée fut lancée et comme on s'est rapidement trouvé dans nos discussions, cela s'est vite organisé.

Ce que je ne savais pas en revanche, c'est que mon ami Romeu MOURA avait eu la même démarche que la mienne mais lui en privé (ils se connaissaient déjà avec Alistair). Au bout d'un moment, Romeu a dû en avoir marre que je le harcèle ;-P et a accepté que ce soit moi qui live-code avec Alistair (il animera une session juste après en mode Q&A du coup ;-)

Pour monter l'événement ensuite, on s'est très vite dit avec Romeu que ce serait bien de faire rencontrer plusieurs publics. Celui des communautés DDD Paris, Crafting Software et Software Crafts(wo)manship Paris. Et puis, pour éviter qu'un meetup plus actif que les autres ne vole la vedette (et les places disponibles) aux autres communautés, on s'est dit qu'il fallait séparer le quota de places à distribuer sur chaque meetup. De faire 3 invitations identiques, mais séparées du coup.

InfoQ FR : Reste-t-il encore de la place pour s'inscrire ? Si ce n'est pas le cas, pourrons-nous revoir cet exercice de style ?

Thomas : Il n’y a plus de place, l'événement s'est retrouvé plein en quelques minutes seulement, ce qui nous a poussé à chercher un lieu plus grand que celui trouvé initialement.

Pour la captation vidéo on ne le sait pas encore. On aimerait bien enregistrer cette session, mais reste à définir comment. Avec les équipes d'InfoQ ?

Evaluer cet article

Pertinence
Style

Contenu Éducatif

BT