Le découpage d'un logiciel

Parfois plus compliqué que celui de la dinde de Noël.

A chaque fois que je peux découper mon code en plus petits modules, j'ai le sentiment que c'est mieux comme ça.

Car il est toujours plus simple de décomposer un problème complexe en une somme de petits problèmes simples. On maîtrise mieux ce qu'on fait. C'est plus facile à tester et à faire évoluer.

Chaque jour voit émerger un nouveau concept, une nouvelle architecture, ou un nouveau framework qui est micro-quelque-chose.

Le macro, c'est has-been. C'était du temps d'IBM. Désormais on découpe en faisant les plus petits morceaux possibles de code et de serveurs.

L'avantage c'est aussi la résilience. Si un module subit une panne ou un bug, cela n'affecte pas le système tout entier. Seule une fonction est perdue, mais l'application reste partiellement utilisable.

Et puis des modules indépendants permettent le passage à l'échelle. En cas de besoin, on multiplie les instances comme des petits pains sur des petits serveurs distribués, et cela permet d'absorber les pics de charge.

Et c'est ainsi que votre projet est lancé sur des micro-services qui communiquent entre eux et avec des micro front-ends. Et pour ne pas gâcher tout ça avec une base de données monolithique, on la répartit sur plusieurs serveurs, ou encore mieux on la découpe en plusieurs base de données indépendantes.

Quels sont les risques d'un découpage raté ?

J'en vois quelques uns, dont certains m'ont amené à faire un peu machine arrière sur certains projets.

Risque #1 : on ajoute de la complexité

C'est exactement l'inverse de l'objectif recherché. Parce qu'en découpant en petites entités, il va falloir drastiquement augmenter le nombre de liens entre les entités.

Ceux qui un jour ont débuggé un joyeux bazar de lambdas functions, SQS, CloudWatch et DynamoDB sur AWS peuvent probablement en témoigner.

Risque #2 : des interfaces avec un mauvais niveau d'abstraction

On rencontre cette difficulté lorsqu'on décompose à outrance un objet. Par exemple :

  • un cahier est composé de feuilles…

  • … comportant une entête, un pied de page et une zone d'écriture…

  • … composée de lignes…

  • … comportant une zone dans la marge et une ligne d'écriture…

  • …comportant un trait normal surmonté de 4 traits légers.

soit 5 niveaux de décomposition ! Au 4ème, on ne sait même plus que l'on parle d'un cahier.

Et la moindre fonction simple, comme "ajouter un mot" peut devenir un calvaire lorsqu’elle impose de connaître le détail de cette décomposition.

Risque #3 : la cohérence des données est difficile à maintenir

A tout moment, il est nécessaire d'avoir dans votre projet une source de vérité unique. Combien y-a-t-il d'articles en stock ? Qui sont les utilisateurs ayant souscrit à l'offre payante ?

En répartissant les traitements, on travaille à divers endroits avec des copies locales et temporaires des données. Au final, qui dispose de la version à jour ? Comment évite-t-on de générer des doublons ?

C'est un risque qui augmente avec le nombre d'utilisateurs simultanés. Pendant les tests, tout va bien. Mais peu après la mise en production, les accès simultanés se multiplient. Certains bugs apparaissent et sont difficiles à traquer.

Comment éviter ça dans votre projet ?

Voila deux principes utiles :

  • Le meilleur découpage est celui qui comporte le plus grand nombre de modules avec le plus petit nombre de liens.

  • Les données qui servent à calculer d'autres données sont centralisées.

Il ne faut pas chercher le volume, il faut rechercher l'indépendance.

Réfléchissez à la structure de votre projet : de quoi est-il composé ? Peut-on trouver une meilleure organisation ? Quelles sont les informations centrales qui vont servir partout ? Existe-t-il un cheminement naturel des informations ?

On reste parfois bloqué sur un découpage qui copie/colle l'organisation de son entreprise : tel module pour le marketing, tel module pour le commercial. Chacun chez soi.

Mieux vaut renverser cette façon de penser en imaginant plutôt le cheminement des informations : "une campagne de publicité génère des opportunités commerciales qui sont transformées en contrats de prestation".

Non seulement ça bénéficie à l'architecture du logiciel que l'on réalise, mais ça révèle aussi des possibilités de mieux faire coopérer les équipes.

Bonne semaine !

— Hervé