Clean Architecture - Et si on passait à côté ?

Je vois de plus en plus la Clean Architecture comme le SCRUM. Quelque chose qui est souvent mal appliqué et mal compris. Quelque chose dont on oublie ou met de côté la philosophie, l’essence même. Quelque chose qu’on utilise parce que c’est à la mode.

J’observe un nombre grandissant de discussions autour de la Clean Architecture. C’est davantage présent dans les projets, dans les souhaits, dans les échanges, dans les publications. Pourtant, je pense qu’une (trop grande) partie des personnes passe à côté de concepts essentiels et ne se pose pas les bonnes questions. Malgré la bonne intention, ça peut être dangereux. J’aimerais amorcer une prise de recul et ouvrir des questions.

Et si on prenait du recul ?

Je vois des discussions qui tournent seulement autour du pattern, du diagramme de classe. “Le Presenter fait ceci et cela. Il parle à celui-ci ou à celui-là." Quand je demande ce qu’est la Clean Architecture, on me répond souvent en me récitant un diagramme de classe. Pas un mot sur l’abstraction, l’entrée/sortie, l’inversion de contrôle, … Et encore moins sur l’isolation du métier.

J’ai également assisté à des entretiens et des échanges avec des développeurs qui s’acharnent avec des suites de questions pour savoir si Machin va plutôt dans le Router ou Interactor ou Presenter, si c’est pas à Bidule de faire ça, et le rôle de Truc là-dedans, … Plutôt que de parler de l’esprit de la Clean Architecture, ils ne parlent que des classes.

Certaines équipes utilisent la Clean Architecture comme cadre pour empêcher les développeurs d’en sortir, en suivant un modèle à la lettre. Faire sans comprendre, sans réfléchir ne mène pas très loin. À quel point cela vaut le coup, de rendre des choses difficiles, d’ajouter de la complexité pour empêcher des développeurs de sortir des rails ? Il y a peut-être d’autres choix à explorer.

Dans tout ça, on oublie le pourquoi. On se concentre trop sur le comment. Pourquoi on l’utilise ? “C’est pour découper. C’est pour pouvoir tester." me dit-on souvent, sans trop détailler. Oui, mais pourquoi ça devient “plus découpé”, “plus testable” ? Quels concepts y a-t-il derrière ? Pourquoi fait-on cela ?

Et si on se recentrait sur le métier ?

Le métier est la partie la plus importante du produit. Sans métier, le produit n’existerait pas, l’équipe ne le fabriquerait pas. C’est le cœur du programme et de l’entreprise. Certaines règles vont au-delà du programme. La répartition des places dans un train par exemple. Cette règle peut être présente dans plusieurs programmes différents et existe même en dehors de tout ça, dans le monde réel.

Ces règles ne dépendent pas d’un choix technique ou d’un framework, elles ne sont pas affectées par un changement technique. On change de base de données ? Pas de problème. On n’a pas encore choisi la base de données ? Pas de problème non plus. On change de framework ? Aucun souci.

Les règles devraient pouvoir changer aisément, le monde évolue constamment. On devrait les trouver et les comprendre facilement puisque c’est le cœur du programme. C’est pour toutes ces raisons qu’il est important d’apporter une grande attention sur cette brique. De la protéger de l’extérieur. De la rendre compréhensible, lisible. De la tester.

Le schéma de Clean Architecture représenté par les 4 cercles va d’ailleurs dans ce sens. On retrouve les règles métiers et les règles applicatives au centre. Et uniquement ça. Pas de framework, pas de base de données, pas d’interface graphique. Les frontières protègent les cercles à l’intérieur de l’extérieur. C’est aussi l’esprit de l’architecture hexagonale et du DDD (Domain-Driven Design).

Le métier est au centre parce qu’il est très important. Parce qu’on veut le protéger. Parce qu’on veut en prendre soin. Le reste, c’est du détail. Du détail d’implémentation.

Et si on se penchait sur les principes ?

La programmation orientée-objet a son rôle à jouer, bien plus que ce que l’on apprend souvent à l’école (vous savez, ce fameux héritage pour classifier des animaux). Certains concepts qui gravitent autour de la POO se cachent derrière la Clean Architecture et sa séparation des couches.

L’abstraction par exemple. Avec l’abstraction, on cache les détails de l’implémentation. On veut utiliser quelque chose sans savoir comment ça fonctionne derrière. On s’enlève cette complexité. Je veux enregistrer un favori sans savoir de quelle manière il sera stocké.

L’inversion de contrôle et l’injection de dépendances sont un autre exemple. Ces concepts sont présents pour renforcer les frontières, pour protéger les cercles. On veut que les cercles discutent entre eux, mais sans qu’un cercle intérieur n’ait connaissance d’un cercle extérieur. On découple. Un Use Case peut interagir avec une base de données sans que ce code ne soit à l’intérieur du cercle, de son module. Cette brique est indépendante. Ainsi, les changements autour de la base de données ne vont pas affecter le Use Case. Et c’est tout de même le Use Case qui est aux commandes, qui utilise la base de données.

On parle de modularité en programmation orientée objet. D’autres concepts sont également là. Je vous conseille de prendre le temps de les découvrir et de les comprendre. De voir comment tout cela s’articule, et d’aller au-delà de la Clean Architecture. S’ils ne vous intéressent pas, alors prenez encore plus de temps pour creuser le sujet. Mais n’en restez pas à l’application d’un pattern.

Et si on explorait plus loin ?

La Clean Architecture apporte de bonnes choses, mais ce n’est pas une silver bullet pour autant. La solution miracle n’existe pas. C’est une solution parmi d’autres. Il faut la comprendre, savoir ses forces et faiblesses, connaître ses principes, l’approfondir.

Il faut également explorer ce qu’il y a autour. L’architecture hexagonale est une approche similaire par exemple. Elle accorde beaucoup d’importance au métier, le place au centre et le protège avec un système de ports et d'adapters. Une approche simple qui se marie très bien avec le Domain-Driven Design (un tas de choses à voir là-dedans, je recommande pleinement de s’y plonger). Le Functionnal Core, Imperative Shell me semble être un autre moyen intéressant.

Et il faut garder en tête les différents principes de programmation. Ils sont toujours là, peu importe le choix de l’architecture. Ils vous accompagneront pendant longtemps.

Cherchez à comprendre et approfondissez, n’appliquez pas sans réfléchir. Soyez ouvert et explorateur, ne restez pas enfermé dans une vision unique. Et appréciez :)