En revue de code, quelqu’un vous écrit : « tu dupliques, factorise ». Vous factorisez. C’est un bon conseil, il s’appuie sur un principe connu, et la personne qui vous l’a donné a raison.
Six mois plus tard, la fonction factorisée prend quatre paramètres, contient
trois if qui n’ont rien à voir entre eux, et personne n’ose y toucher. C’est
devenu le pire fichier du projet.
La personne qui vous a conseillé de factoriser avait raison. Le résultat est mauvais. Les deux à la fois.
Pourquoi deux principes justes peuvent se contredire
Un principe est de l’expérience compressée. Quelqu’un a vu la même chose échouer vingt fois, en a tiré une phrase courte, et cette phrase vous évite de refaire les vingt erreurs.
La compression a un coût, et c’est toujours le même : ce qu’on retire, c’est le contexte. La phrase survit, les conditions dans lesquelles elle était vraie disparaissent.
graph TD
E1[Une expérience
dans un contexte] --> P1[Principe A]
E2[Une autre expérience
dans un autre contexte] --> P2[Principe B]
P1 --> C{Appliqués au
même code}
P2 --> C
C --> R[Ils se contredisent]
class R attentionDeux principes issus de contextes différents finissent donc par se rencontrer sur le même bout de code et par se contredire. Ce n’est pas que l’un est faux. C’est que la question de savoir lequel s’applique n’est écrite nulle part — et c’est exactement le travail qu’on vous demandera de faire.
Voici trois de ces désaccords. Ils n’opposent pas une bonne règle à une mauvaise : ils opposent des gens sérieux entre eux.
1. DRY contre la mauvaise abstraction
D’un côté : Don’t Repeat Yourself, formulé par Andrew Hunt et David Thomas dans The Pragmatic Programmer1. Chaque connaissance doit avoir une seule représentation dans le système. Dupliquer, c’est se condamner à corriger deux fois — et à en oublier une.
De l’autre : Sandi Metz, dans un texte de 2016 devenu une référence2, retourne le conseil : « la duplication coûte bien moins cher que la mauvaise abstraction. » Son scénario est celui du début de cet article. On factorise deux choses qui se ressemblent, puis un cas particulier arrive, on ajoute un paramètre, puis un autre — jusqu’à un code que plus personne ne comprend. Et défaire une abstraction est bien plus difficile que de dupliquer.
Les deux ont raison, sur des situations différentes. La question qui les départage n’est pas « est-ce que ça se ressemble ? » mais :
Ces deux morceaux changeront-ils toujours ensemble ?
Si oui, ce sont deux exemplaires de la même chose : factorisez. Si non, ils se ressemblent aujourd’hui par coïncidence, et la duplication est honnête.
Notez au passage que la position de Metz est elle-même contestée, publiquement, par des gens compétents. C’est plutôt rassurant.
2. Petites fonctions contre modules profonds
D’un côté : Robert C. Martin, dans Clean Code3, défend des fonctions très courtes — quelques lignes — qui font une seule chose. Le découpage rend chaque morceau lisible.
De l’autre : John Ousterhout, dans A Philosophy of Software Design4, soutient l’inverse : un bon module est profond, c’est-à-dire qu’il offre une interface simple pour une implémentation complexe. Découper à l’excès produit des modules « peu profonds », dont l’interface coûte presque aussi cher à comprendre que le code qu’elle cache. Multiplier les petites fonctions ne supprime pas la complexité : elle la déplace dans les relations entre elles.
Ce désaccord-là a une particularité remarquable, et c’est la meilleure chose que je puisse vous montrer dans cet article : les deux auteurs en ont débattu publiquement, par écrit, entre septembre 2024 et février 2025, sur la longueur des méthodes, les commentaires et les tests. Ils ont tout publié5.
Allez lire ce document. Pas pour savoir qui gagne — personne ne gagne. Pour voir deux personnes qui ont écrit des livres de référence défendre des positions incompatibles avec des arguments sérieux. C’est le meilleur antidote qui existe à l’idée qu’il y aurait, quelque part, la bonne façon de faire.
La question qui vous servira devant votre propre code :
Est-ce que découper réduit ce que l’appelant doit savoir — ou est-ce que ça le répartit sur plus d’endroits ?
3. « Assez bien » contre la règle du boy-scout
D’un côté : Hunt et Thomas défendent le good enough software1 — savoir s’arrêter, livrer, et laisser l’utilisateur juger. La perfection n’est pas livrable, et polir au-delà du nécessaire est un coût que personne n’a demandé.
De l’autre : la règle du boy-scout, popularisée par Martin3 : laisser le code un peu plus propre qu’on ne l’a trouvé, à chaque passage. Sans quoi la dégradation est lente, continue, et invisible jusqu’au jour où plus rien ne bouge.
Contradiction directe : l’un vous dit d’arrêter, l’autre d’en faire un peu plus que le nécessaire.
Qui paiera la différence, et quand ?
Si c’est vous, la semaine prochaine, sur ce même fichier : nettoyez. Si c’est un utilisateur qui attend depuis trois semaines une fonctionnalité qui marche : livrez. La réponse dépend de qui supporte le coût, pas d’une préférence esthétique.
Ce que ça change à la façon de lire un principe
Regardez les trois questions. Aucune n’est un principe, et c’est le point.
Un principe n’est pas une règle, c’est une question déguisée. DRY ne dit pas « ne dupliquez jamais » ; il demande si deux choses sont la même chose. Pris comme une règle, il produit le fichier à quatre paramètres du début. Pris comme une question, il devient utilisable.
C’est aussi ce qui distingue un développeur débutant d’un développeur expérimenté, et ce n’est pas la quantité de règles connues. C’est de savoir laquelle s’applique ici, ce qui demande d’avoir compris de quelle expérience chacune a été comprimée.
D’où la seule chose à retenir de trente principes, qui est aussi la dernière :
Les règles sont un point de départ, pas une destination.
Et la meilleure façon de le vérifier n’est pas de me croire. C’est d’aller lire deux auteurs qui ne sont pas d’accord, et de constater qu’il va falloir trancher soi-même.
Références
Ces principes sont extraits d’un ouvrage en cours d’écriture. Il n’est pas encore disponible, et cet article ne suppose pas de le lire : les trois questions ci-dessus s’utilisent telles quelles.
Hunt, A. & Thomas, D. (1999). The Pragmatic Programmer. Addison-Wesley. Pour DRY et le good enough software. ↩︎ ↩︎
Metz, S. (20 janvier 2016). The Wrong Abstraction. sandimetz.com ↩︎
Martin, R. C. (2008). Clean Code. Prentice Hall. Pour les fonctions courtes et la règle du boy-scout. ↩︎ ↩︎
Ousterhout, J. K. (2021). A Philosophy of Software Design (2ᵉ éd.). Yaknyam Press. Première édition en 2018. ↩︎
Ousterhout, J. & Martin, R. C. (2024-2025). A Philosophy of Software Design vs. Clean Code. github.com/johnousterhout/aposd-vs-clean-code ↩︎