7 avril 2022 Nicolas Delauney

Parlez vous développeur ? DDD, TDD, et autres acronymes barbares

Si vous vous êtes déjà retrouvé(e) entouré(e) de développeurs(euses) il est probable qu’ils ou elles aient utilisé un langage cryptique réservé aux seul(e)s initié(e)s. Pas de panique ! Aujourd’hui ARCA vous propose une introduction aux concepts qui nous sont chers pour comprendre nos amis du code, et expliquer simplement des disciplines dites « clean code ».

« La MEP d’hier s’est déroulée comme sur des roulettes ! En même temps avec la CI en place et le TDD qu’on utilise, on peut y aller les yeux fermés. »

Vous n’avez rien compris ? Comme toute discipline, le métier de développeur à construit au fil du temps son langage propre, avec ses termes barbares pour se différencier du commun des mortels. Dédicace à ma compagne qui supporte mes babillages avec plus ou moins de patience. Et d’avance, toutes nos excuses aux anglophobes, beaucoup si ce n’est la majorité des termes sont d’origine anglaise.

Nous pouvons d’ors et déjà classifier les termes que nous allons voir en 2 catégories : le vocabulaire « ops » (néologisme anglais pour désigner les « opérations »), c’est à dire tout ce qui va concerner la vie du produit une fois qu’il a été développé, et le vocabulaire « méthode », qui va regrouper diverses manière de penser et écrire le code, de l’architecture au nommage.

# 1. Clean Code, et Software Craftsmanship

La plupart des méthodes sont regroupées sous l’égide « Clean Code« , qui renvoie à faire du code propre, élégant et qu’il sera facile de maintenir et de faire évoluer. Cette notion est très souvent accompagnée de la philosophie de vie idoine : le Software Craftsmanship, c’est à dire l’artisanat logiciel. Pas dans le sens fait à la main dans son coin, mais dans le sens noble des métiers d’artisanats. Rappelons qu’à la racine du mot « artisanat« , il y a « art« . De plus en plus de développeurs se revendiquent bien plus que de simples « pisseurs de code », et apprécient faire leur métier avec le temps et le soin d’un artisan.

J’en entends déjà se plaindre que dans le milieux compétitif de la tech, le temps est un luxe qu’on ne peut pas se permettre. Détrompez vous ! Partout où j’ai vu le Software Craftsmanship appliqué, le code est bien souvent en meilleur santé et peu coûteux à maintenir. Certes, l’effort initial est plus grand, mais sur le long terme ça finit par payer. Évidemment, tous les contextes sont différents, et un client qui désire un produit le plus vite possible n’est pas le même besoin qu’un produit interne qu’on vendra sur plusieurs années.

 

Maintenant que tout est dit, nous passerons en revue quelques uns de ces termes, dans l’ordre logique du cycle de vie du code : conception, réalisation, production.

# 2. Conception

Avant même d’écrire un bout de code pour son application, on peut réfléchir à comment on va coder un produit. De nombreuses architectures existent, nous avons décidé de vous en présenter deux aujourd’hui.

DDD

Le « Domain Driven Development« , ou Développement Conduit par le Domaine, vise à établir un vocabulaire commun entre tous les acteurs (on parle d’ubiquitous language). Plutôt dans le thème non ? Le but est d’éviter les dialogues de sourds entre, par exemple, les développeurs, les personnes qui établissent les règles métiers, et les utilisateurs finaux. Et ça va du nommage des entités, au nommage des variables et des méthodes ! Tout le code devient une traduction presque parfaite d’une règle énoncée dans un langage « humain ».

Imaginons une application de gestions d’un parc de téléphones mobiles. L’utilisateur parlera de téléphone, le métier de terminal, et le code de device. Bonjour la galère quand il s’agit d’expliquer une fonctionnalité, ou de traiter un problème ! Avec le DDD, tout le monde se met d’accord sur un terme (disons, terminal), et le code devient le reflet parfait du métier. En remettant le métier au coeur du projet, et non pas les considérations techniques, on s’assure que les besoins et évolutions du métier sont toujours en phase avec le code applicatif.

per-loov-oXqn2CXC_9Q-unsplash

Photo by Per Lööv on Unsplash

 

En allant encore plus loin, le DDD peut radicalement changer la manière d’approcher un problème. Reprenons notre gestion de terminaux. Si l’utilisateur veut créer un nouveau terminal, il arrivera sans doute sur une page de création / édition. Il arrive souvent que dans ce cas, le choix entre création ou édition se fait par la présence ou non d’une entité Terminal. Le développeur doit alors gérer du code comprenant à la fois l’utilisation d’une entité, et sa nullité, soit deux cas distincts. Le DDD vous dit alors que la nullité ne fait pas partie du langage connu, il vaudrait mieux créer une entité NewTerminal, qui dépend fortement de la première. Une fois le domaine en place, votre code n’aura plus qu’à gérer une entité Terminal, avec quelques cas marginaux pour les entité filles comme NewTerminal. Et demain, qui sait si le métier ne va pas arriver avec un nouveau vocabulaire ? Votre code s’y adaptera d’autant mieux qu’il parle déjà la langue du métier.

Architecture Hexagonale

L’architecture hexagonale est en quelque sorte la suite logique du DDD. Dans cette architecture (manière d’organiser le code et ses dépendances), le domaine est un temple sacré. Il définit non seulement les entités, mais aussi des interfaces qui explicitent ce qu’on a le droit de faire avec le domaine. Par exemple, une interface du domaine pourrait définir une méthode permettant de récuperer un terminal, getTerminalByID(id: String). Mais le rôle du domaine s’arrête là, et c’est en cela qu’il est sacré. D’une part, le domaine explicite au monde extérieur les possibilité, mais ne connaît pas le détail d’implémentation. D’autre part, tout le code qui ne parle pas du métier ne doit pas modifier le code du domaine. C’est à dire, que le domaine ne doit avoir absolument aucune dépendance, et ne peut donc pas connaître, par exemple, la manière dont sera sauvegardée la donnée, ou comment celle-ci transitera sur internet. Par contre, ces couches là auront la charge d’implémenter les interfaces du domaine, et par injection de dépendances tout ce petit monde discutera sans peine.

Architecture hexagonale

Le but de cet article est de vulgariser ces termes, nous ne rentrerons donc pas plus dans les détails (pour l’instant). Mais l’avantage de l’architecture hexagonale est d’explicitement séparer des bouts de code qui n’ont rien à voir entre eux. Imaginez que votre produit fait appel à un service web A, et utilise une base de données grand public pour la sauvegarde. Demain, un client vous demande d’utiliser un service web B, avec une sauvegarde sur sa propre base de donnée inconnue de tous. Enfer et damnation ? Pas du tout, il suffit de redéfinir les couches externes, grâce aux interfaces du domaine. Le métier ne change pas, les API et les bases de données peuvent coexister sans problème, et pour un coût minimisé puisqu’une grande partie de l’effort à déjà été réalisé.

# 3. Réalisation

Maintenant que l’on sait comment on souhaite architecturer (=ranger) notre code, voyons comment s’assurer d’un code de qualité. Quel drôle de mot, qu’est-ce que ça veut dire de la qualité pour du code ? Pas de risque de contamination, ou de saleté dans le produit… Pour un développeur, les risques sont les attaques (sécurité du code) et les bugs (stabilité du code).

TDD

Encore un anglicisme : Test Driven Development, pour Développement Conduit par les Tests. L’idée derrière le TDD est assez simple : tester tout le code qu’on écrit, avec en tête le plus petit pas possible. Avant de foncer bille en tête et de coder un gros pavé qui fait le café et les croissants, on se pose et on réfléchit. On veut de l’eau chaude, puis des grains moulu, puis une percolation, et on a son café. Et les croissants dans tout ça ? Et bien en fait on en voulait pas : en écrivant uniquement les tests qui traduisent un besoin, on n’écrit pas de code superflu. Donc moins de code à maintenir. Et en écrivant les tests les uns après les autres, en se forçant à augmenter la complexité pas à pas, on s’assure en même temps de ne pas introduire de régression dans le code, puisque tous les tests doivent toujours passer.

Mais écrire du code petit à petit n’est pas efficace, et le code résultant ne sera pas optimisé ? Rassurez-vous : le TDD fonctionne comme un cercle vertueux :

  1. On écrit un test qui décrit une partie du besoin (la plus petite possible). Il ne doit pas passer puisque le comportement n’existe pas
  2. On écrit le code du comportement, pour faire passer le test
  3. Maintenant que tous les tests (le nouveau et les précédents) sont ok, on réfléchit à améliorer le code

En résumé, la méthode TDD est garante de la stabilité du code.

TDD

Linter et Qualité de code

Chaque développeur est unique, avec son expérience et ses habitudes, et tout le monde n’écrit pas de la même manière un code équivalent. Chaque langage a ses propres subtilités, et pour avoir une base de code uniforme, des outils appelés linters vont parcourir le code écrit et appliquer une série de règles  communes (par exemple: sauter une ligne à la fin d’un fichier) pour tous les développeurs d’une même équipe. Ces linters, comme Prettier ou Black, assurent une cohésion du code, et peuvent être exécutés sur chaque fichier au fur et à mesure de l’écriture, avant la sauvegarde du fichier, avant le partage… Du moment qu’ils passent avant que le code soit en production, en clair.

Maintenant que le code est stable, des outils extérieurs comme SonarQube ou encore Codacy vont analyser le code pour vérifier que la couverture est bonne, c’est à dire que tous les brins de code sont « couverts » par des tests, et aussi que le code n’est pas « à risque » en utilisant des failles qui sont connues des hackers pour attaquer un produit. Ces outils vont aussi vérifier les « Code Smells« , des bouts de code susceptibles de provoquer des bugs. En effet, l’analyse statique du code, sans même l’exécuter, permet bien souvent de détecter ces erreurs qui fragilisent la sécurité d’une application.

Codacy

Interface de Codacy

# 4. Production

Le code est propre, stable, et analysé. Comment et quand pour rassembler toutes ces étapes, et surtout, que fait-on du code écrit ?

CI/CD

En réalité, deux concepts, mais suffisamment proches pour être toujours côte à côte. La CI, pour Continous Integration (intégration continue), va permettre d’automatiser certains processus, pour vérifier que le code est conforme en continue. La CI va par exemple rejouer les tests pour vérifier qu’ils passent bien, lancer l’analyse statique du code (cf précédemment), compiler les différents module et tout rassembler au même endroit. C’est un peu le dernier garde fou avant de déployer du code.

Ce qui nous amène au CD : Continuous Deployement (déploiement continu). Dans un monde parfait, la CI est aussi responsable de déployer le code directement en production, c’est à dire de mettre à disposition aux utilisateurs la dernière version possible. C’est le Graal du développement, puisque si toutes les étapes précédentes sont validées, le code se retrouve au plus vite en production. Et si la CI est bien construite pour faire les bonnes vérifications, déployer ne devrait pas être une contrainte.

1*GzIKSeQMoFCXQ-q1bxzsgA

Sauf que ce n’est pas si simple. Certains produits ont besoin d’être arrêtés, puis redémarrés, pour prendre en compte les changements. Donc on ne peut pas faire ça n’importe quand pour ne pas couper le services aux utilisateurs. D’autres produits ont des processus de déploiements tellement complexes qu’ils sont extrêmement durs à automatiser. Et enfin, la production c’est toujours le saut dans l’inconnu : plus de filets, la catastrophe guette à chaque coin. Donc beaucoup de sociétés vont avoir tendance à être frileuses sur le déploiement continu : il faut une personne physique pour prendre en charge le processus, pour avoir un(e) responsable à désigner.

MEP

C’est la conclusion de tous nos efforts. L’aboutissement de cet article. Et en même temps, l’un des acronymes les plus simples ! Mise En Production. Basique. Ce qui l’est moins, c’est son utilisation à outrance par les personnes qui mettent en production ou ont besoin de savoir ce qui a été déployé. Parce que plus qu’un acronyme, MEP est aussi un adjectif, un verbe, un nom. On peut dire « La MEP du jour », « ce que j’ai meppé », etc. Et c’est très étrange à écrire mais ce langage oral est pratiqué par beaucoup par abus, jusqu’au jour où nous vaincrons et rentrerons dans le dictionnaire !

Voilà pour aujourd’hui. Nous espérons que cet article vous permettra de mieux comprendre nos chers barbus, et peut-être de découvrir certains concepts qui méritent un approfondissement bien plus vaste que ces quelques lignes. Et si d’aventure un mot barbare rencontre votre chemin, n’hésitez pas à demander !