Ce billet est le deuxième d'une série sur le conception de logiciels[1].

Je m'intéresse aujourd'hui à la manière dont évolue la structure d'un logiciel, notamment en ce qui concerne les concepts dont on a pu parler précédemment.

Il y a fort longtemps, les cours que j'ai pu avoir en relation avec le développement logiciel avaient toujours une approche assez constructiviste : avant d'écrire la moindre ligne de code, on commence par découper un problème donné en problèmes élémentaires, puis on réfléchit aux concepts que l'on va utiliser, ensuite on commence a écrire des bouts de code que l'on va assembler pour parvenir au logiciel final.

En suivant cette démarche, on commence par définir l'architecture du logiciel avant d'en réaliser les détails :

2x01.png

Et même au niveau des détails, on est amené à suivre la même approche. On commence par implémenter quelques concepts de base avant de les assembler :

2x02.png

Cette approche a le mérite d'être analogue à certains domaines de l'ingénierie ("on crée le plan avant de réaliser l'ouvrage") mais, en ce qui me concerne, elle survit difficilement à la réalité du développement logiciel.
Je n'ai jamais vu quelqu'un bâtir intégralement un logiciel comme on construirait une maison. A un moment ou à un autre, le logiciel dévie sensiblement du moindre plan que l'on aurait pu faire. En fait, par certains aspects, un logiciel ressemble à un organisme...

Organisme : entité biologique, unicellulaire ou pluricellulaire, capable de se développer et de se reproduire.

Dans le phénomène probablement le plus connu de la reproduction cellulaire, la mitose[2], une cellule croit et se divise pour au final donner deux cellules génétiquement identiques mais qui peuvent être fonctionnellement différenciées.

Mitose

Il en va un peu de même pour la formation des concepts d'architecture d'un logiciel. Lorsqu'une implémentation grossit, des abstractions apparaissent et, si tout se passe bien, l'implémentation se divise en deux parties indépendantes mais rattachées par ces nouvelles abstractions.

2x03.png

Pour rester dans le même type d'analogie, on pourrait aussi évoquer la réparation d'une plaie cutanée[3] : l'organisme s'auto-répare lorsque survient une blessure légère.

Dans un logiciel, le code blessé est celui qui, devenu trop complexe, ne peut plus évoluer correctement. L'émergence de concepts d'implémentation répare le code et lui permet d'aller de l'avant.

2x04.png

Bref, même si de bons concepts peuvent être pensés a priori, il ne faut pas abuser de la chose. Un logiciel qui évolue harmonieusement à partir de besoins de conceptualisation avérés (une abstraction qui émerge, une implémentation qui se simplifie) a de meilleures chances d'évoluer et croitre qu'une créature de Frankenstein assemblée à partir de morceaux choisis en amont.

Le défi dans l'évolution d'un logiciel, c'est la manière dont un développeur arrive à la contrôler. Cela sera le sujet d'un prochain billet.