L'architecture hexagonale
Published: 2022-06-29 04:32:36

Ce nom vous dit probablement quelque chose car on en entend de plus en plus parler. Pourtant son origine n’est pas si récente. L’architecture hexagonale ou encore Ports & Adapters Pattern date de 2005, quand Alistair Cockburn en décrit les contours. 

Habituellement, dans nos projets Spring Boot nous utilisons l’architecture n tiers mais ce n’est pourtant pas la seule manière de construire une application. Pour certains, l’architecture hexagonale peut même apparaître comme plus cohérente car elle remet la logique métier au cœur de nos développements. 

Le but principal de cette architecture étant de bien dissocier les besoins métier des algorithmes, on peut tout à fait l’utiliser pour des langages back mais aussi front. Ici, je vais surtout parler de sa mise en place dans un framework Spring Boot mais cela marche également pour les autres frameworks. 

Avant de vous en présenter les avantages, j’aimerais vous montrer globalement à quoi cela ressemble.
L’architecture n tiers que l’on connaît bien :
![architecture n tiers](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d81zcp8ub9c8rlcga0zs.png)

Et l’architecture hexagonale…
![architecture hexagonale vue macro](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5shctdosr34gkqwjpz1t.png)

![architecture hexagonale en détail](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s7h7pdtnrlacvyxdx6qb.png)


## Un exemple! Un exemple! Un exemple!
Ok 😄 Prenons un exemple concret. Nous souhaitons réaliser une application permettant de créer des événements (sportifs, culturels, caritatifs, etc…). L’idéal serait évidemment de pouvoir ensuite les rechercher à tout moment, les filtrer par ville, type, prix, etc…de pouvoir les modifier, les supprimer, etc…bref une application complète 🙂 Mais là pour notre exemple, on va simplement s’intéresser à la création d’un événement.
Et on n’oubliera pas d’implémenter deux règles métier pour mettre en avant la logique métier de notre projet. Ici, je vais par exemple dire que si un événement a lieu dans le passé, il ne sera pas créé. Et de même si un événement caritatif est créé avec un prix de participation à l’événement alors il ne sera pas créé. 

Dans notre **Domain**, on y trouve l’ensemble des objets dont a besoin notre métier. Ici, l’objet <u>Event</u>. 
![Image 1 architecture hexagonale](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bzu3r668ncmyiukz81lz.png)

Dans notre **User side port**, on va y trouver un certain nombre d’interfaces (idéalement une par domain visé) qui vont lister l’ensemble des besoins métier. Ici, on aura une interface <u>ICreateEvent</u> dans laquelle on aura la méthode <u>create</u>.
![Image 2 architecture hexagonale](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ru5w5e7d0l9goat137um.png)

Dans notre **service**, on va y trouver un certain nombre de classes Service (idéalement une par domain visé), chacune détaillant les méthodes de nos interfaces juste au-dessus. Ici, on aura une classe <u>EventService</u> qui va implémenter <u>ICreateEvent</u>. On va donc définir ce que la méthode <u>create</u> doit faire. Ça peut être un calcul propre au métier ou ça peut simplement être un appel à une des interfaces de notre server side port. Ici on fera un appel à l’interface <u>ISaveEvent</u>. 
![Image 3 architecture hexagonale](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/878x1kzv4fmamexa5eku.png)

Dans notre **Server side port**, on y trouve aussi un certain nombre d’interfaces mais cette fois-ci il s’agit de lister l’ensemble des méthodes dont on va avoir besoin côté infrastructure pour agir sur la base de données ou le fichier de données qu’on a, et on répartit ces méthodes par interface (idéalement une par domain visé)   
Ici, on aura notre interface <u>ISaveEvent</u> qui contiendra la méthode <u>save</u>.
![Image 4 architecture hexagonale](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gcw0f84tl9gwhm22k28h.png)

Dans notre **controller**, c’est comme avec une architecture n tiers, on définit les endpoints de notre API. On prendra également soin de créer un controller par domain visé. Ici ce sera par exemple <u>EventController</u>. 
![Image 5 architecture hexagonale](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fk91iq1wje2xxb5tc3j2.png)

Dans notre **DTO**, on définit les éventuels DTO dont on a besoin.
![Image 6 architecture hexagonale](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/givqo508pmh1saz0o75m.png)

Dans notre **entity**, on y trouve les objets utiles au métier que l’on a éventuellement modifiés pour correspondre à notre base de données. On passe d’objet à entity. Ici on aura par exemple <u>EventEntity</u>. 
![Image 7 architecture hexagonale](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r96o0xdbyxpneo6ycgep.png)

Dans notre **adapter**, on va définir précisément toutes les méthodes dont notre logique métier a besoin pour réaliser des actions dans notre système de sauvegarde de données. Ici, on aura <u>EventAdapter</u> qui implémente notre interface <u>ISaveEvent</u> et qui va décrire précisément ce que doit faire la méthode <u>save</u>. Ça peut être un simple appel à un repository mais on peut aussi en profiter pour transformer notre objet en entity si nécessaire. 
![Image 8 architecture hexagonale](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/03fubzkgb07yv641wmjx.png)

Dans notre **Repository**, on y trouve toutes les méthodes qui vont réaliser les requêtes sur notre système de sauvegarde de données. Ici, on aura par exemple <u>EventRepository</u>. 
![Image 9 architecture hexagonale](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t8cv1qu2wv9fn8mgpxwg.png) 

Dans le dossier **config** on y met toute la configuration dont a besoin notre application. Ici on a un <u>BeanConfig</u> et un <u>SecurityConfig</u>. 
![Image 10 architecture hexagonale](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ex8ulau1t8rwi5ir8u1w.png)

Vous pouvez retrouver le code [ici](https://github.com/l3ss13ux/demo-les-events)


## Pourquoi avons-nous besoin d’un BeanConfig? 
Habituellement, sous Spring Boot par exemple (mais ce pourrait être avec un autre framework ce serait pareil) lorsque nous utilisons nos classes et nos interfaces, les beans sont automatiquement créés par Sring Boot. C’est toujours le cas dans notre partie infrastructure mais plus dans notre partie logique métier puisque celle-ci doit être totalement indépendante du framework utilisé. Nous devons donc nous même créer les beans utilisés dans la partie logique métier.


## Avez-vous fait attention au sens des flèches sur les schémas? 
Ils sont très importants! Je le répète encore une fois car c’est vraiment la base de l’architecture hexagonale 😃 : **la logique métier doit être totalement indépendante**. Mais nous devons la faire communiquer avec l’infrastructure pour que notre projet fonctionne. Pour cela, nous devons toujours faire appel à notre logique métier dans notre infrastructure mais jamais l’inverse.


## Et les avantages dans tout ça?
Comme promis, j’y viens 😉

- **redonner du sens à nos développements** car on part de choses concrètes qui sont ici les besoins métier et on va réfléchir à comment traduire cela en algorithmes alors que dans une architecture n tiers, on part d’une structure figée dans laquelle on essaie de faire rentrer les besoins métier et on peut avoir tendance à les complexifier inutilement 

- **limiter les systèmes legacy** car on peut changer beaucoup plus facilement la partie infrastructure sans impacter les besoins métier se trouvant dans la partie logique métier

- **une meilleure gestion de la dette technique** car les futurs développements n’entraîneront que peu de coûts supplémentaires sur l’ensemble du projet. S’il s’agit d’améliorer l’interface utilisateur ou de mieux gérer le traitement des données, on sait qu’il ne faut s’intéresser qu’à une partie du projet et non à sa globalité. Et de même, tant que les besoins métier ne changent pas, si de nouveaux développeurs arrivent dans l’équipe, il n’est pas nécessaire qu’ils perdent du temps à les comprendre puisqu’ils n’auront pas à toucher à cette partie du code

- **des tests moins contraignants**. Nous devons réaliser des tests sur l’ensemble de notre projet mais la partie la plus importante est la partie logique métier, et puisqu’elle est isolée de l’infrastructure, les tests sont plus faciles et rapides à réaliser et à maintenir


## Des inconvénients?
Eh oui! Comme pour tout il y a quelques inconvénients :

- **la courbe d’apprentissage est un peu plus élevée**

- **les projets sont plus volumineux** qu’en n tiers

- **une organisation de l’application en couches**, le projet est plus segmenté et il faut s’y tenir sinon on perd les avantages de faire de l’architecture hexagonale


## Pour conclure
L’architecture hexagonale est une réelle alternative dans la construction de nos projets. Elle ne sera peut-être pas adaptée à tous les projets mais elle vaut vraiment le coup d’apprendre à la découvrir et de la populariser car elle replace les besoins finaux, et donc l’intérêt de nos développements, au cœur de nos projets.