Tous les développeurs expérimentés connaissent cette situation : vous héritez d’un projet legacy et tombez sur un commentaire datant de plusieurs années. Depuis, le code a été modifié des dizaines de fois. Peut-on vraiment faire confiance à cette documentation ? Ce dilemme, bien connu dans le métier, révèle un paradoxe frappant : la documentation la plus fiable se trouve souvent dans le code lui-même. Un code bien structuré, avec des noms explicites et des règles métier claires, communique bien mieux que des pages de documentation souvent obsolètes.
Les problèmes de la documentation traditionnelle
Les limites de la documentation traditionnelle sont bien connues :
- Obsolescence inévitable : Alors que le code évolue constamment, la documentation, elle, reste souvent en retrait, créant un décalage qui peut facilement induire en erreur.
- Maintenance chronophage : La mise à jour de la documentation exige du temps et de la rigueur, souvent négligés lorsque les échéances approchent. Elle est perçue comme une tâche secondaire, avec un retour sur investissement immédiat limité pour les équipes.
- Risque accru d'erreur : Une documentation obsolète peut s'avérer plus nuisible que l'absence totale d'information. Elle risque de semer la confusion chez les nouveaux développeurs et, au final, de miner la confiance dans les informations documentées.
Exemple parlant :
// ATTENTION - obsolète
// Calcul avec TVA à 19.6%
function calculatePriceWithTax(price: number): number {
return price * 1.20; // TVA actuelle 20%
}
Ce simple exemple montre à quel point un commentaire peut devenir trompeur, tandis que le code, lui, reflète toujours la réalité.
La solution : Faire de votre code la meilleure documentation
Un nommage explicite
Les noms sont souvent le premier outil de documentation. Ils permettent de donner un sens immédiat au code sans nécessiter d’explications supplémentaires. Prenons un exemple pour comparer deux approches de nommage :
// ❌ Avant : Cryptique et peu parlant
function p(d: number, t: number): number {
return d * (1 + t / 100);
}
// ✅ Après : Auto-documenté
function calculatePriceWithTaxRate(
priceExcludingTax: number,
taxRatePercentage: number
): number {
return priceExcludingTax * (1 + taxRatePercentage / 100);
}
Dans le second exemple, le nom des paramètres et de la fonction est explicite, permettant de comprendre le but du code au premier coup d'œil.
Une architecture narrative
Un code bien structuré raconte une histoire. Chaque classe ou méthode représente une étape cohérente de cette histoire. Par exemple, une classe de gestion de commandes pourrait organiser ses méthodes pour montrer chaque phase de traitement : calcul du sous-total, application des remises et ajout de la TVA.
class Order {
private readonly items: OrderItem[];
constructor(items: OrderItem[]) {
this.items = items;
}
calculateTotal(): number {
const subtotal = this.calculateSubtotal();
const discountedPrice = this.applyDiscounts(subtotal);
return this.addTax(discountedPrice);
}
private calculateSubtotal(): number {
return this.items.reduce(
(total, item) => total + item.price,
0
);
}
private applyDiscounts(amount: number): number {
// Logique de remise
return amount;
}
private addTax(amount: number): number {
// Application de la TVA
return amount * 1.20;
}
}
La structure ici rend le flux de calcul clair : chaque étape est isolée, et le code devient facile à suivre, quasiment sans commentaire.
Les tests comme documentation vivante
Les tests unitaires, en plus de garantir le bon fonctionnement, servent de documentation en explicitant le comportement attendu. Ils montrent des cas d’utilisation réels et ce que le code devrait produire, ce qui aide à comprendre ses objectifs.
Les cas où la documentation reste nécessaire
Certains éléments du code nécessitent une documentation ciblée pour garantir une compréhension globale et éviter les malentendus.
- Architecture système : Les diagrammes d'architecture, les flux de données et les interactions entre services fournissent une vue d'ensemble indispensable.
- Décisions techniques ou produit : Les choix structurants et compromis importants doivent être documentés, pour conserver une trace des décisions.
- APIs publiques et configurations complexes : Les APIs externes et les paramètres de déploiement ou variables d'environnement nécessitent une documentation claire pour en garantir la bonne utilisation.
- Règles métier : Les règles métier complexes, les exceptions et les cas spéciaux doivent être documentés pour assurer une compréhension globale et éviter les malentendus.
Conclusion
Un code de qualité est la meilleure documentation. En investissant dans un nommage explicite, une structure claire et des tests complets, vous créez un code auto-explicatif qui réduit la dette technique et facilite la maintenance sur le long terme. Pour approfondir, explorez Clean Code de Robert C. Martin, Working Effectively with Legacy Code de Michael Feathers