Coulée de lave.
La coulée de lave est un antipatron où du code obscur et inachevé se fige en production, car personne ne le comprend assez pour oser le supprimer.
Dans le jargon de la programmation informatique, la coulée de lave est un anti-pattern qui survient lorsqu'un code source écrit dans des conditions sous-optimales est déployé dans un environnement de production puis étendu alors qu'il est encore à l'état de développement. Le terme dérive du phénomène naturel de la lave qui, une fois refroidie, se solidifie en roche difficile à enlever. De même, un tel code devient difficile à refactoriser ou à remplacer en raison des dépendances qui apparaissent au fil du temps, obligeant à maintenir la compatibilité ascendante avec la conception d'origine, incomplète.
Causes
La coulée de lave peut survenir pour diverses raisons au sein d'un processus de développement logiciel :
- La pression des délais qui transforme des solutions temporaires en solutions permanentes
- Une documentation insuffisante qui empêche de comprendre l'objet du code
- L'absence de tests automatisés qui rend le refactoring risqué
- Des changements fréquents dans l'équipe de développement entraînant une perte de connaissances
Conséquences
Un code non affiné qui devient partie intégrante de l'infrastructure du logiciel accroît la complexité du système, et la base de code devient de plus en plus difficile à comprendre et à maintenir. Cela entraîne :
- Le besoin de compatibilité ascendante qui peut étouffer l'innovation et empêcher l'adoption de solutions plus récentes et plus efficaces
- Une dette technique accrue qui s'accumule au fil du temps, augmentant les coûts de modification et de maintenance
- Des obstacles au refactoring ou à l'amélioration du système par crainte de casser les composants dépendants
Impact sur les équipes
Les équipes de développement subissent souvent l'impact de la coulée de lave lorsque les membres de l'équipe se renouvellent :
- Perte de connaissances sur certains aspects du code du système lorsque les développeurs d'origine partent
- Réticence des nouveaux développeurs à refactoriser un code qu'ils ne connaissent pas, ce qui accroît encore la complexité car ils ajoutent au lieu de nettoyer
Stratégies d'atténuation
Plusieurs pratiques peuvent atténuer les effets de l'anti-pattern de la coulée de lave :
- Promouvoir de bonnes pratiques de documentation pour une compréhension claire du code
- Encourager des revues de code régulières pour détecter tôt les pratiques sous-optimales
- Prioriser le refactoring comme partie intégrante du cycle de vie du développement
- Maintenir une suite complète de tests automatisés pour réduire le risque lors des changements
Exemple
La branche héritée ci-dessous survit à chaque nettoyage : aucun test, aucun ticket, aucune documentation, seulement un commentaire d’avertissement. Personne ne sait à quoi elle sert, et personne n’ose la supprimer.
class Pricing {
// personne ne sait qui active ce drapeau ; ne pas supprimer, quelque chose pourrait casser
private static final boolean LEGACY_MODE = Boolean.getBoolean("pricing.legacy");
double price(Order order) {
double total = order.total() * 1.1;
if (LEGACY_MODE && order.items() > 10) {
total = legacyAdjust(total); // ???
}
return total;
}
private double legacyAdjust(double total) {
return Math.floor(total * 0.97);
}
}
La solution consiste à capturer le comportement actuel par des tests de caractérisation, à vérifier que la branche n’est pas utilisée, puis à la supprimer :
// 1. Des tests de caractérisation figent le comportement actuel avant toute modification
@Test
void addsTenPercentMarkup() {
assertEquals(110.0, new Pricing().price(new Order(100.0, 1)), 1e-9);
}
// 2. Une recherche dans le code et la configuration de production montrent que personne ne définit pricing.legacy,
// la branche est donc supprimée ; les tests confirment que rien d’autre n’a changé
class Pricing {
double price(Order order) {
return order.total() * 1.1;
}
}
Du code inatteignable n’est que du code mort, et le gestionnaire de versions le conserve de toute façon : inutile de le garder « au cas où ».
Adapté de l’article Wikipédia “Lava flow (programming)” (révision 1309138267), disponible sous licence CC BY-SA 4.0 ; le texte a été traduit et modifié, et des exemples ont été ajoutés.