Retour sur NCrafts / Le refactoring par la pratique

Ce billet de blog fait partie de la série consacrée à la conférence NCrafts qui s’est tenue à Paris le 16 Mai 2014.
Le sujet
Cette session traite d’un sujet récurrent dans le parcours d’un consultant : comment transformer une solution, dans laquelle il est difficile de faire évoluer les technologies utilisée ? En d’autres termes, comment rendre le code facile à maintenir et faire évoluer ?
Le speaker
Le speaker s’appelle Julien Lavigne (@julienlavigne), il travaille comme consultant / lead technique pour Criteo et a eu l’occasion de travailler sur différents projets dans différents domaines.
Sa présentation avait la particularité d’être très axée, non pas sur des théories ou des bonnes pratiques lues dans des livres ou sur des blogs, mais sur son retour d’expérience au cours de ses différents projets.
La problématique
La plupart du temps, les développeurs ont une vision assez simplifiée et uniforme de l’architecture logicielle. Lorsqu’un projet démarre, les équipes de dev ont très souvent tendance à suivre le même schéma :
- Création du modèle conceptuel de données (très souvent dans du SQL),
- Définition des couches graphiques,
- Conception de développement des couches intermédiaires
Le nombre de couches intermédiaires peut varier en fonction du projet (Business, DTO, DAO…).
Avec l’évolution de l’application développée, chacune des couches grossie (par l’ajout de nouvelles fonctionnalités et de nouvelles données utilisées). On finit par se retrouver avec un code extrêmement varié (à cause de fonctionnalités, elles aussi très variées), et lié à une énorme base de données qu’il devient difficile de faire évoluer.
Ce code legacy (sur lequel nous sommes tous déjà tombés) pose souvent les problèmes suivants :
- Il est impossible d’effectuer des livraisons partielles, on est obligés de livrer la totalité de l’application pour toute modification d’une fonctionnalité,
- Les refactos / migration vers de nouvelles technos deviennent long et chers, très chers…
- On est obligé de faire avec les technos choisies au départ (vieilles car difficiles à faire
évoluer), même si elles ne sont pas adaptées à toutes les fonctionnalités.
La solution proposée
La solution proposée dans cette session est assez simple. Le problème est résumé en une phrase : Nous avons appris à découper (notre architecture) dans le mauvais sens.
Comprenez qu’au lieu de démarrer par un découpage horizontal tout de suite suivi par le choix des technos pour chacune des couches, il vaut mieux commencer par un découpage vertical par composants (regroupant des fonctionnalités) et réfléchir ensuite à une architecture et des technos adaptées à chacun des composants.
La méthode présentée consiste à identifier parmi les fonctionnalités celles qu’il est avantageux de regrouper. Ces groupements de fonctionnalités correspondent ensuite aux différents composants de l’application (il est aussi tout à fait possible d’avoir des composant techniques offrant des services mais n’étant associés à aucune fonctionnalité en particulier).
Il faut également définir pour chaque composant les contrats / façades et les modes de communication (REST, WCF, Message Bus…) permettant la communication.
Les avantages de ce découpage sont les suivants :
- La possibilité d’effectuer des livraisons par composants au lieu de systématiquement livrer tout l’applicatif: cela apporte plus de souplesse dans le développement de nouvelles fonctionnalités.
- Il devient possible d’avoir une architecture et un schéma de données optimisés pour chacun des modules.
- Le refactoring et les migrations sont moins lourds et moins risqués (en termes de régression) car ils sont effectués par module.
En pratique, il n’est évidemment pas toujours possible de diviser un code déjà existant en sous modules en une fois.
Le speaker préconise donc de détecter un groupe de fonctionnalités, de les sortir dans un composant et de mettre à jour le reste de l’application pour qu’elle utilise le nouveau module en question.
Il faut ensuite réitérer ces opérations… à plusieurs reprises…
Au cours de cette session, nous n’avons vu aucune ligne de code. Mais la problématique était intéressante. En ce qui me concerne, je me suis retrouvé face au même problème au cours d’une précédente mission pour un site de eCommerce. Leur solution était effectivement devenue trop imposante et toutes les équipes (travaillant chacune sur un module fonctionnel différent) utilisaient la même solution.
Il pouvait alors arriver que certaines livraisons prennent plus de temps que prévu (par exemple à cause de bugs rencontrés sur l’environnement de préprod), cela avait pour effet de bloquer toute livraison de n’importe quelle autre équipe travaillant sur la solution.
L’entreprise de eCommerce en question a adopté une solution semblable à celle décrite au cours de cette session.
Pour aller plus loin, les slides de la session sont sur slideshare: http://fr.slideshare.net/Julionn/refactor-your-software-architecture