Les frontières avant les abstractions
Les codebases les plus pénibles ne manquent pas d'abstraction. Elles ont des abstractions au mauvais endroit. Les frontières viennent d'abord ; les abstractions se méritent ensuite.
- Architecture
- Clean code
- Refactoring
Demandez ce qui rend un codebase difficile et on vous répondra « spaghetti », autrement dit pas assez de structure. Mon expérience est plutôt l'inverse : les pires codebases débordent de structure. Des classes de base à un seul héritier. Des services génériques paramétrés pour des cas jamais advenus. Des helpers qui enrobent deux lignes d'une librairie. De la structure partout, des frontières nulle part.
La distinction
Une frontière est une ligne qu'on s'engage à ne pas franchir à la légère : la logique métier n'importe pas le framework HTTP ; l'UI ne connaît pas la forme des lignes en base ; un module parle à un autre à travers une surface explicite. Une abstraction est un mécanisme : interface, classe de base, wrapper. Les abstractions sont une façon d'implémenter une frontière, mais on peut avoir cent abstractions et aucune frontière.
Ce sont les frontières qui achètent réellement la tolérance au changement. Quand les règles de chiffrage sont séparées des contrôleurs qui les exposent, changer une règle est un diff d'un fichier. Quand le frontend consomme une couche d'accès aux données typée plutôt que des réponses brutes du CMS, changer la façon de récupérer le contenu touche un module. Ni l'un ni l'autre n'exige d'inventer un pattern ; les deux exigent de décider où sont les lignes et de les tenir.
Pourquoi l'abstraction prématurée échoue
Une abstraction créée avant le deuxième cas d'usage est un pari sur le futur. La plupart des paris sont perdus, et une mauvaise abstraction est pire que la duplication : elle couple chaque appelant à une forme que le métier n'a jamais demandée, et la défaire coûte plus cher que le doublon n'aurait jamais coûté. La duplication est bon marché à résorber précisément au moment où l'on comprend enfin le pattern. C'est là que l'abstraction devient méritée plutôt que spéculative.
Un ordre qui fonctionne
Tracez d'abord les frontières : ce qui est métier, ce qui est infrastructure, qui parle à qui. Gardez le code à l'intérieur de chaque frontière aussi simple que possible : fonctions, modules, types explicites. Laissez la duplication exister jusqu'à ce qu'elle fasse mal, puis extrayez l'abstraction que les cas réels réclament. Dans cet ordre, les abstractions restent petites, honnêtes et remplaçables. Dans l'ordre inverse, on obtient un framework que personne n'a demandé au-dessus d'un métier que personne n'a séparé.