4 points par GN⁺ 2024-10-30 | 1 commentaires | Partager sur WhatsApp

Écrire du code facile à supprimer

  • Chaque ligne de code entraîne un coût de maintenance. La réutilisation du code rend les modifications plus difficiles.
  • Plus une API a de consommateurs, plus il faut réécrire de code lors d’un changement.
  • Gérer les dépendances du code est un enjeu important dans les systèmes à grande échelle.

Étape 0 : ne pas écrire de code

  • Le nombre de lignes de code ne fournit pas en soi beaucoup d’informations.
  • Le code qu’on n’a pas écrit est le plus facile à supprimer.

Étape 1 : copier-coller du code

  • Le code réutilisable peut être écrit plus facilement plus tard à partir d’exemples.
  • Le copier-coller est une façon d’éviter les dépendances et de gagner en flexibilité.

Étape 2 : ne pas faire de copier-coller

  • Quand le code a été suffisamment copié-collé, il est temps de l’extraire dans une fonction.
  • Il est utile de créer un répertoire util pour stocker divers utilitaires dans d’autres fichiers.

Étape 3 : écrire davantage de boilerplate

  • Le boilerplate ressemble au copier-coller, mais on modifie le code à des endroits différents.
  • Le boilerplate réduit les dépendances et apporte de la flexibilité.

Étape 4 : ne pas écrire de boilerplate

  • S’il y a trop de boilerplate, il faut l’envelopper dans une bibliothèque qui exprime une opinion sur les politiques, les workflows et l’état.
  • La relation entre requests et urllib3 en est un bon exemple.

Étape 5 : écrire de gros blocs de code

  • La logique métier se caractérise par une infinité de cas particuliers et des hacks rapides et sales.
  • Il est plus facile de supprimer une grosse erreur que de supprimer plusieurs petites erreurs.

Étape 6 : découper le code en morceaux

  • Les gros blocs de code ont un coût de maintenance élevé.
  • Il faut séparer les responsabilités du code et concevoir les modules en tenant compte de leur probabilité d’évolution.

Étape 7 : continuer à écrire du code

  • Il faut pouvoir écrire du nouveau code indépendamment du code existant afin d’expérimenter de nouvelles idées.
  • Les feature flags sont un moyen de pouvoir changer d’avis plus tard.

Résumé de GN⁺

  • Cet article explique comment écrire du code facile à supprimer.
  • L’essentiel est de réduire les dépendances du code, d’augmenter la flexibilité et de diminuer les coûts de maintenance.
  • Parmi les projets aux fonctionnalités proches, on trouve requests et urllib3.
  • Cet article rappelle aux développeurs logiciels l’importance de la gestion du code et de la maintenance.

1 commentaires

 
GN⁺ 2024-10-30
Avis sur Hacker News
  • J’aime bien la formule « Simple is robust ». Cela signifie que moins un système est complexe, plus il est facile à faire évoluer. Il faut planifier pour l’avenir avec du code intuitif plutôt qu’avec du code pensé pour l’extensibilité. Par exemple, n’abstraire que lorsque la situation l’exige, encourager les duplications simples, utiliser un monolithe au départ et privilégier le scale-up au scale-out. Après avoir construit plusieurs systèmes de type 0→1, j’y ai retrouvé ces points communs.

  • Je suis surpris qu’il n’y ait aucune mention des tests ni de l’observabilité. Les tests ont un coût de maintenance, mais ils réduisent le risque de casse quand on supprime du code. Quand on expose un service à des appelants externes, il faut un moyen solide de marquer certains appels comme dépréciés et d’observer s’ils sont encore utilisés. J’ai récemment supprimé de façon semi-automatique des résolveurs GraphQL, et des métriques de fréquence d’usage m’ont permis d’identifier ceux qu’on ne pouvait pas retirer. GraphQL a bien des annotations de dépréciation, mais le service ne les traitait pas spécialement. En ajoutant de l’observabilité pour lever un indicateur lorsqu’une fonction dépréciée est appelée, puis en laissant tourner cela en production suffisamment longtemps, on peut supprimer en toute sécurité du code exposé à l’extérieur.

  • Cela m’a amené à promouvoir l’idée de « concevoir pour la suppression ». Autrefois, je pensais pouvoir tout prévoir et construire une œuvre couvrant tous les besoins, mais il est difficile d’anticiper les besoins futurs. Un jour, ce que j’ai créé deviendra inutile pour quelqu’un, et il sera légitime de le démanteler. Il faut donc faire l’effort de le rendre facile à retirer. Cela conduit souvent à réduire le couplage, mais ce n’est pas la même chose que vouloir tout découper en frameworks métaconfigurables comme le font certains jeunes développeurs. Parfois, un couplage étroit est préférable quand il rend la logique plus facile à comprendre.

  • Pour écrire du code facile à supprimer, il faut dupliquer pour éviter les dépendances, et non dupliquer pour faciliter la gestion. Il faut séparer les couches du code et construire des API simples à partir de composants simples à implémenter mais peu pratiques à utiliser directement. Il faut isoler le code, et séparer du reste les parties difficiles à écrire et celles qui ont le plus de chances de changer. Il ne faut pas tout coder en dur ; il faut permettre de modifier certaines choses à l’exécution. D’après mon expérience, le code facile à supprimer est structuré en couches et modularisé, ce qui le rend aussi facile à étendre.

  • Je dis toujours aux étudiants en physique computationnelle que le meilleur calcul est celui dont on n’a pas à se soucier.

  • Personnellement, je sépare le code entre logique métier et implémentation concrète. La logique métier peut, par nature, comporter des duplications, mais trop de détails techniques ne devraient pas être dupliqués. Tant qu’on garde la logique métier indépendante de l’application sans la faire traiter directement par elle, elle peut être aussi désordonnée qu’on veut. Si un problème survient et que cela fonctionne mal, on a la possibilité de supprimer toute l’implémentation, de la corriger, sans être forcé d’aller chercher la vraie spécification dans le code d’implémentation.

  • Erreur évidente dans le premier paragraphe : le problème de la réutilisation du code serait qu’elle empêche de changer d’avis plus tard. C’est généralement faux. Si on change d’avis et que le code a été copié-collé à dix endroits, il faut modifier dix endroits. Si, au contraire, le code est dans une fonction, il ne faut le changer qu’une fois. Si l’un des dix appels ne doit finalement pas changer, on peut toujours le copier-coller à ce moment-là, ou rendre la fonction plus générale. Comme traverser la rue sans regarder autour de soi, le copier-coller est presque toujours une mauvaise idée.

  • Il existe une excellente corrélation : le mauvais code reste longtemps parce qu’il est difficile à retirer.

  • Je me demande si cela veut dire qu’il faut utiliser les logiciels le plus possible dans leur état par défaut, sans aller trop loin dans la personnalisation.