Pourquoi retarder le choix d'un framework va vous aider

Vous venez d'acheter une nouvelle voiture plus spacieuse pour emmener toute la famille en vacances.

Tout heureux de cette nouveauté, vous constatez dès le premier jour que vous ne pouvez plus fermer la porte de votre garage. La nouvelle voiture est plus longue que l'ancienne...

Mais pourquoi n'avez-vous pas pensé à ça ?

Simplement parce que vous avez oublié le lien de dépendance entre la voiture et la taille du garage. Vous avez pensé à tous les autres (budget, rachat de l'ancienne voiture, les prochaines vacances, ...). Mais pas à celui-ci.

En s'essayant à tracer les liens de dépendances sur cet exemple, on pourrait arriver à ça :

Les flèches signifient "dépend de".

"Vacances en famille" dépend de la taille de la voiture (trop petite = pas possible d'emmener tout le monde) et du budget vacances (insuffisant = pas de vacances).

"Taille de la voiture" dépend entre autre du budget d'achat (une grande voiture coûte + cher qu'une petite).

etc.

Remarquez le sens des flèches.

  • L'item "vacances en famille" (en vert) n'a que des flèches qui partent vers d'autres boites. Parce que rien ne dépend de lui. Si vous changez vos plans et décidez de partir en vacances à Cherbourg au lieu de Nice, ça n'a pas d'impact sur le reste.
  • A contrario, l'item "budget total" (en rouge) n'a que des flèches qui arrivent vers lui. Cela signifie qu'il influence beaucoup de choses. Divisez par 2 ce budget total, et tout le projet est à revoir.

Dans la vie, les choses dépendent les unes des autres. Elles sont interconnectées par des liens de dépendances.

Et bien dans le code, c'est pareil.

Le code spaghetti

Lorsque j'ai commencé à coder il y a plus de 30 ans, tout était regroupé dans 1 seul et unique fichier.

Mais rapidement, c'est devenu ingérable et ça limitait la ré-utilisation du code pour plusieurs projets. Alors on a découpé le code en modules.

A présent, chaque projet logiciel est un assemblage de modules. Certains déjà codés et prêts à l'emploi (les "librairies", les "framework", ...), et d'autres non.

Même un petit projet atteint vite la centaine de modules. Les modules sont comme les boites de notre exemple : ils dépendent les uns des autres. Chaque module utilisé s'appuie lui-même sur d'autres modules, qui utilisent d'autres modules, ...

La complexité du projet atteint parfois un niveau tel que plus personne n'en possède la maîtrise globale. Le graphe des dépendances d'un projet ressemble parfois à ça :

D'accord, ça semble un peu embrouillé.

Mais après tout, en quoi est-ce gênant ?

Surtout ne toucher à rien.

Un code n'est jamais terminé.

On veut pouvoir le faire évoluer : le changer ou ajouter des fonctionnalités.

Et parfois on subit des évolutions de librairies externes qu'on ne maîtrise pas.

Est-ce facile de gérer ces changements ?

Comme pour les vacances en famille, la faisabilité d'un changement dans le code va varier selon l'extrémité sur laquelle on se trouve.

Un module "rouge" utilisé par tous les autres va être très difficile à modifier. Par contre, un module "vert" pourra évoluer sans trop de risque de provoquer une pagaille de bugs.

Voila un principe tout simple expliqué dans le livre Clean Architecture d'oncle Bob (qui pourrait être un peu plus mince, le livre hein, pas oncle Bob, quoique) :

Mettez ce qui risque de changer souvent dans des boites vertes (peu utilisées par d'autres modules) et ce qui est stable dans les boîtes rouges (très utilisées par les autres).

Vous pensez que c'est un peu théorique comme principe de codage, car tout change tout le temps.

En fait non :

  • l'interface utilisateur, les APIs, ou les bibliothèques externes changent souvent,
  • mais le code "coeur de métier" qui modélise les données et les processus de l'entreprise tend à être plus stables.

Alors dans votre prochain projet, mieux vaut commencer par l'épicentre du code et retarder autant que possible le choix des outils externes (framework, base de données) et le peaufinage des aspects graphiques.