💡 Key Takeaways
- Rule I Follow #1: Functions Should Do One Thing (But I Define "One Thing" Differently)
- Rule I Follow #2: Meaningful Names Are Non-Negotiable
- Rule I Follow #3: Comments Explain Why, Not What
- Rule I Follow #4: Keep Functions and Classes Small (With Nuance)
J'ai regardé le code des autres pendant 14 ans maintenant en tant qu'architecte logiciel senior dans une entreprise fintech de taille moyenne, et je peux vous dire exactement quand j'ai cessé d'être un fanatique du code propre : c'était à 2 h 47 du matin un mardi de mars 2019, lorsque notre système de traitement des paiements est tombé en panne parce que quelqu'un avait passé trois jours à refactoriser un module parfaitement fonctionnel pour suivre chaque règle du livre de l'oncle Bob. L'ironie ? Le bug a été introduit lors du "nettoyage."
💡 Points clés
- Règle que je suis #1 : Les fonctions doivent faire une seule chose (mais je définis "une seule chose" différemment)
- Règle que je suis #2 : Des noms significatifs sont non négociables
- Règle que je suis #3 : Les commentaires expliquent pourquoi, pas ce qu'ils font
- Règle que je suis #4 : Gardez les fonctions et les classes petites (avec nuance)
Cette nuit-là a changé ma manière de penser à la qualité du code. Je ne dis pas que les principes du code propre sont faux—loin de là. Mais après avoir examiné plus de 10 000 demandes de tirage, encadré 47 développeurs et expédié 23 versions majeures de produits, j'ai appris que l'adhésion dogmatique à un ensemble de règles n'est qu'une autre forme de dette technique. Certaines règles de code propre sont de l'or pur. D'autres ? Elles dépendent du contexte au mieux, et sont activement nuisibles au pire.
Voici ce que je fais réellement dans le code de production, et surtout, pourquoi je le fais.
Règle que je suis #1 : Les fonctions doivent faire une seule chose (mais je définis "une seule chose" différemment)
Le principe de responsabilité unique pour les fonctions est probablement la règle la plus précieuse que je suis religieusement. Mais voici où je diverge du manuel : je ne mesure pas "une seule chose" par lignes de code ou par le nombre d'opérations. Je la mesure par la cohésion conceptuelle.
Au dernier trimestre, j'ai examiné une fonction qui faisait 8 lignes mais violait le SRP de manière spectaculaire. Elle validait l'entrée utilisateur ET enregistrait le résultat de la validation ET mettait à jour un cache. Trois responsabilités distinctes regroupées en 8 lignes. Comparez cela à une fonction de 45 lignes que j'ai écrite le mois dernier qui orchestre une transaction de base de données complexe—elle fait "une seule chose" (compléter une transaction de paiement), mais cette unique chose nécessite plusieurs étapes qui appartiennent ensemble.
Voici mon test décisif : puis-je décrire ce que fait cette fonction en une seule phrase sans utiliser le mot "et" ? Si je dois dire "cette fonction valide l'entrée ET envoie un e-mail", elle fait deux choses. Mais si je dis "cette fonction traite une demande de remboursement," et que cela implique naturellement la validation, des mises à jour de base de données et une notification—c'est encore une seule chose au bon niveau d'abstraction.
En pratique, cela signifie que mes fonctions font en moyenne 25-30 lignes au lieu des 10-15 recommandées par les puristes. Mais notre taux de bugs sur ces fonctions est 40 % plus bas que sur le code trop extrait que nous avions auparavant. Pourquoi ? Parce que garder des opérations liées ensemble réduit la charge cognitive de compréhension du système. Lorsque tout est divisé en petites fonctions, vous passez plus de temps à sauter entre les fichiers qu'à comprendre la logique métier.
Le véritable gain ici est la testabilité. Une fonction qui fait une seule chose conceptuelle est facile à tester, même si elle fait 40 lignes. Vous simulez les dépendances, appelez la fonction, affirmez le résultat. Fait. Lorsque vous avez extrait tout en fonctions de 5 lignes, vous vous retrouvez avec des tests d'intégration de toute façon parce que les tests unitaires deviennent sans signification.
Règle que je suis #2 : Des noms significatifs sont non négociables
Je mourrai sur cette colline : les noms de variables et de fonctions sont la documentation la plus importante que vous écrirez jamais. J'ai rejeté des demandes de tirage uniquement à cause de mauvais noms, et je le ferai encore.
"L'adhésion dogmatique à un ensemble de règles n'est qu'une autre forme de dette technique. Le meilleur code n'est pas le plus propre—c'est le code qui s'expédie de manière fiable et qui peut être maintenu par votre équipe."
Il y a deux mois, un développeur junior a soumis un code avec une fonction appelée `processData()`. Je l'ai renvoyé avec une vidéo Loom de 10 minutes expliquant pourquoi. Cette fonction validait spécifiquement les numéros de cartes de paiement selon l'algorithme de Luhn. Le nom correct était `validateCardNumberChecksum()`. Oui, c'est plus long. Oui, c'est plus spécifique. C'est précisément le but.
Voici ma hiérarchie de nommage, affinée au fil de milliers de revues de code :
- Variables booléennes : Commencez toujours par is/has/can/should. Pas `active`, mais `isActive`. Pas `permission`, mais `hasPermission`.
- Fonctions : Verbes pour les actions, noms pour les requêtes. `calculateTotalPrice()` pas `totalPrice()`. `getUserById()` pas `user()`.
- Classes : Noms qui représentent des concepts, pas des actions. `PaymentProcessor` pas `ProcessPayments`.
- Constantes : SCREAMING_SNAKE_CASE pour les vraies constantes, camelCase pour la configuration qui pourrait changer.
L'impact est mesurable. Après avoir mis en œuvre des conventions de nommage strictes dans notre équipe il y a 18 mois, notre temps moyen de révision PR est passé de 3,2 heures à 1,8 heures. Pourquoi ? Parce que les examinateurs passent moins de temps à déchiffrer ce que fait le code et plus de temps à évaluer s'il le fait correctement.
J'impose également une règle "pas d'abréviations" avec exactement trois exceptions : `id`, `url`, et `api`. Tout le reste doit être écrit en toutes lettres. `usr` devient `user`. `btn` devient `button`. `calc` devient `calculate`. Les touches supplémentaires en valent la peine lorsque quelqu'un débogue à 23 heures et n'a pas à deviner ce que signifie `tmpBfr`.
Règle que je suis #3 : Les commentaires expliquent pourquoi, pas ce qu'ils font
J'ai vu deux extrêmes dans ma carrière : des bases de code avec zéro commentaires et des bases de code où chaque ligne a un commentaire. Les deux sont faux, mais le code trop commenté est en fait pire parce qu'il crée un fardeau de maintenance et ment souvent.
| Règle du Code Propre | Quand suivre | Quand ignorer | Impact dans le monde réel |
|---|---|---|---|
| Les fonctions doivent être petites | Chemins de code à fort trafic, modules fréquemment modifiés | Logique d'orchestration complexe, gestion des transactions | Une division prématurée crée une surcharge de navigation |
| Pas de commentaires dans le code | Logique métier auto-explicative | Algorithmes complexes, exigences réglementaires, optimisations non-évidentes | Un contexte manquant coûte des heures de débogage |
| DRY (Ne vous répétez pas) | Logique métier de base, transformations de données | Code similaire mais contextuellement différent | Une sur-abstraction crée des dépendances fragiles |
| Évitez l'obsession primitive | Modèles de domaine, frontières d'API | Utilitaires internes simples, chemins critiques en termes de performances | Un emballage excessif ajoute une charge cognitive |
Ma règle est simple : si vous expliquez ce que fait le code, le code est probablement mauvais. Si vous expliquez pourquoi vous avez pris une décision spécifique, c'est un bon commentaire. Voici un exemple réel tiré de