1 points par GN⁺ 2024-02-26 | 1 commentaires | Partager sur WhatsApp
  • Pour les projets open source de 10k à 200k lignes de code, placer un document ARCHITECTURE à côté de README et CONTRIBUTING peut réduire le coût, pour les nouveaux contributeurs, de compréhension de la structure du code
  • Dans un projet inconnu, le vrai problème n’est pas tant qu’écrire un patch soit environ 2 fois plus lent, mais qu’il faille 10 fois plus de temps pour trouver où il faut modifier
  • Ce document doit contenir brièvement la structure de haut niveau et ce qui change peu souvent, et il est plus adapté de le réviser quelques fois par an que d’essayer de le garder constamment synchronisé avec le code
  • Les éléments clés sont une vue d’ensemble du problème et une carte du code (codemap), qui montre les grands modules et leurs relations afin de répondre à la question « où se trouve le code chargé de X ? »
  • Il faut conserver les noms importants, les invariants d’architecture, les frontières entre couches et systèmes, ainsi que les préoccupations transverses, mais orienter vers la recherche par nom plutôt que vers des liens directs réduit la charge de maintenance

Le coût réduit par un document ARCHITECTURE

  • Dans un projet open source, la plus grande différence entre un contributeur occasionnel et un développeur core est de savoir ou non comment fonctionne l’architecture physique du projet
  • Dans une base de code inconnue, on lit les fichiers séquentiellement comme des fragments logiques placés dans un ordre arbitraire
  • Un développeur qui a déjà apporté une contribution significative possède une carte mentale du code qui lui permet d’aller directement à l’endroit utile, et sans cela il peut même déplacer le code concerné
  • Le fichier ARCHITECTURE est un moyen peu coûteux de réduire cet écart
  • Le document doit être court
    • parce que tous ceux qui contribuent de façon répétée doivent le lire
    • et parce qu’un document court a moins de chances d’être invalidé par des changements futurs
  • Le critère pour ARCHITECTURE est d’y mettre ce qui ne changera pas souvent
    • sans chercher à le synchroniser en permanence avec le code
    • mais en le réexaminant quelques fois par an

Que faut-il y mettre ?

  • Commencez par résumer le problème que le projet résout au niveau d’une vue d’ensemble
  • Rédigez ensuite une carte du code (codemap) avec un certain niveau de détail
    • elle décrit les grands modules et leurs relations mutuelles
    • elle doit répondre à « où se trouve ce qui fait X ? »
    • elle doit aussi répondre à « que fait ce que je regarde en ce moment ? »
  • Il ne faut pas entrer trop profondément dans le fonctionnement interne de chaque module
    • ce type de contenu doit aller dans un document séparé ou, mieux encore, dans de la documentation inline
    • une carte du code est une carte du pays, pas un atlas régional détaillé
  • Le processus d’écriture de la carte du code permet aussi de revoir la structure du projet
    • vous pouvez vérifier si les éléments que vous souhaitez voir proches sur la carte du code sont également voisins dans le résultat de tree .
  • Les noms importants de fichiers, modules et types doivent être explicitement indiqués
    • il vaut mieux éviter les liens directs, qui peuvent se casser avec le temps
    • à la place, encourager la recherche de symboles par nom permet de découvrir aussi des éléments apparentés aux noms similaires, sans augmenter la charge de maintenance
  • Les invariants d’architecture doivent être écrits explicitement
    • les invariants importants prennent souvent la forme de quelque chose qui « n’existe pas »
    • par exemple, en développement web, le fait que la couche modèle ne dépende pas de la vue peut être difficile à déduire en lisant uniquement le code
  • Les frontières entre couches et systèmes doivent aussi être indiquées
    • une frontière suggère des informations sur l’implémentation du système qui se trouve derrière
    • elle contraint toutes les implémentations possibles
    • comme de bonnes frontières sont difficiles à repérer au hasard dans le code, les documenter est utile
  • Après la carte du code, ajoutez une section distincte pour les préoccupations transverses
  • Un exemple utile à consulter est l’architecture.md de rust-analyzer

1 commentaires

 
GN⁺ 2024-02-26
Commentaires sur Hacker News
  • J’aime bien cette idée, et je pense qu’il y a aussi de la place dans le README pour une description de l’architecture, quelle que soit la taille du dépôt
    Par exemple, je trouvais important que tous les lecteurs puissent voir et comprendre le flux de travail, donc j’ai volontairement mis un diagramme de séquence Mermaid[1] dans le README principal[2]
    [1] https://mermaid.js.org/syntax/sequenceDiagram.html
    [2] https://github.com/hbcondo/revenut-app?tab=readme-ov-file#-w...

    • Ce serait assez génial s’il existait un outil capable de générer des diagrammes Mermaid en langage naturel. Ça vaudrait le coup d’y réfléchir
  • Ça ressemble à un très bon conseil
    J’aimerais que les outils pour visualiser l’architecture d’un système en fonctionnement soient meilleurs. C’est encore étrange qu’aujourd’hui, la méthode la plus moderne consiste toujours à lire le code ou consulter des fichiers Markdown. Avec un peu de chance, on trouve au moins un diagramme Mermaid
    J’aimerais que l’architecture se révèle d’elle-même en temps réel. Ce serait bien si une forme d’observabilité à l’échelle macroscopique était intégrée par défaut, et je pense que cela aiderait tout le monde à mieux comprendre l’informatique et même l’humanité à mieux s’augmenter elle-même

    • Ce serait bien d’ajouter une recherche par mots-clés ou une recherche vectorielle LLM à une visualisation comme dep-tree. On poserait une requête, puis les fichiers et clusters pertinents seraient mis en évidence
  • Pour les projets open source avec beaucoup de contributeurs occasionnels, ça semble être un bon modèle demandant peu de maintenance. Pour les projets disposant d’ingénieurs dédiés, les ADR peuvent aussi valoir le coup
    Les ADR demandent plus de maintenance, mais ils conservent le “pourquoi” et les “alternatives envisagées”, ce qui est très utile lorsqu’on repense l’architecture
    Référence : https://adr.github.io/

    • Ici, “avec” me semble plus juste que “à la place de”
      ARCHITECTURE.md décrit l’état actuel de l’architecture, tandis que les ADR consignent les décisions qui y ont mené. Les deux sont très utiles
    • Dans notre entreprise aussi, il y a des documents inutiles écrits par des architectes, et la plupart ressemblent à ça
      Microservices, Kafka, Kubernetes : au cas où nos 4 000 utilisateurs actuels deviendraient un jour 1 milliard
      GraphDB : au cas où SQL ne suffirait plus
      ElasticSearch : au cas où il faudrait faire de la recherche plein texte en plus des statistiques
      Mais la plupart de ces documents ne sont en réalité qu’une version raccourcie de “j’ai envie d’essayer une nouvelle architecture ou technologie parce que c’est amusant, un collègue passé par la FAANG l’utilise, j’ai lu ce livre, et ça fera bien sur mon CV”
      Puis, une fois qu’ils sont passés à la conception du prochain gros projet, notre équipe doit continuer à synchroniser plus de services que nous n’avons de membres, ainsi que toutes les bases de données et technologies mentionnées ci-dessus. Bien sûr, on nous explique que ce problème est bien plus simple que de prendre de “grandes décisions d’architecture”
  • Je me faisais justement la réflexion : tous les IDE que j’ai utilisés affichent à gauche la structure des dossiers du projet sous forme d’arborescence standard. Existe-t-il un IDE qui permette d’explorer un projet comme un graphe de dépendances ?

    • Ce n’est pas une réponse directe à la question, mais au fond, ça ressemble à “je veux mieux visualiser la structure des fichiers”
      Je ne pense pas qu’une représentation de type table des matières soit très adaptée. Dans mon flux de travail de développement actuel, j’ouvre un terminal, j’y lance ranger, puis je bascule vers ce terminal quand je veux parcourir l’arborescence des répertoires de gauche à droite. J’ouvre VSCode et, dans un terminal scindé, j’ai un terminal classique en haut et Ranger en bas. Midnight Commander fonctionne aussi ; en réalité, n’importe quel explorateur de fichiers en TUI convient
      J’ai aussi commencé à ajouter une carte du code dans le fichier architecture.md du projet. En lançant tree -L , on obtient un diagramme arborescent de la structure des fichiers, facile à insérer dans du Markdown, avec la profondeur voulue. J’ajoute ensuite cette sortie dans le Markdown et j’annote chaque fichier ou dossier d’un court commentaire, de moins de 10 mots, pour décrire son rôle
      Ranger - https://github.com/ranger/ranger
      Midnight Commander - https://midnight-commander.org/
    • J’ai eu exactement la même pensée
      J’ai deux idées de ce à quoi cela pourrait ressembler
      D’abord, plusieurs arborescences de répertoires utilisant des liens symboliques pour organiser les fichiers de façon orthogonale. La structure classique sépare client et serveur, mais si on voulait aussi organiser par fonctionnalité ? Un IDE pourrait rendre ça bien plus simple
      Ensuite, dans l’esprit de cet article, j’aimerais qu’un IDE facilite la création de signets et la navigation entre eux pour expliquer le code à d’autres. J’aimerais parfois laisser des annotations et, au clic, sauter vers un autre endroit du code. En reliant ce genre d’éléments, on pourrait tisser une narration expliquant le fonctionnement de toute la base de code
      Je me demande s’il y a des gens qui travaillent dans cette direction
    • En pratique, à quoi cela ressemblerait-il ? Par exemple, comment gérer des dépendances circulaires ?
    • Peut-être qu’en fait, ce que vous voulez, c’est un multi-arbre
  • Je pense qu’il faut faire attention à ne pas trop généraliser à partir de ce que l’auteur dit ici à l’ensemble des projets logiciels
    Dans les grands projets open source avec beaucoup de contributeurs manquant de contexte, maintenir ce type de document a une vraie valeur. Mais, sur les petits projets internes, j’ai vu tous les documents écrits par des développeurs finir non maintenus

    • J’ai fait quelques sessions d’architecture avec des équipes, et elles ont toujours eu de la valeur
      À tout le moins, on découvre que les membres de l’équipe ont souvent des visions très différentes de l’architecture actuelle et de l’architecture idéale. Rien que le fait de rendre cela explicite suffit à justifier la création du document
      Et l’argument “les documents ne sont pas maintenus” est une raison très faible de ne pas en créer. N’importe quel document, même ancien ou légèrement erroné, vaut mieux que l’absence totale de documentation
  • Il y a quelques années, j’ai testé une approche similaire sur l’un de mes gros side projects.
    https://github.com/shipmight/shipmight/blob/master/src/ARCHI...
    En haut de chaque fichier, j’avais placé un arbre de liens vers les autres fichiers ARCHITECTURE.md du dépôt. Exemple : ARCHITECTURE.md <- position actuelle, backend/ARCHITECTURE.md, backend/api/ARCHITECTURE.md, backend/cli/ARCHITECTURE.md, backend/ui/ARCHITECTURE.md, backend/utils/ARCHITECTURE.md, frontend/ARCHITECTURE.md, internal-charts/ARCHITECTURE.md

  • Plus c’est court, moins ça risque d’être invalidé par des changements futurs. La règle empirique essentielle d’ARCHITECTURE est de n’écrire que ce qui ne change pas souvent. Il ne faut pas essayer de le synchroniser avec le code.
    Les interfaces ont moins de chances de changer, et elles sont aussi plus difficiles à modifier. C’est la perspective de Parnas sur les critères utilisés pour décomposer un système en modules.
    Je suis d’accord sur le fait qu’une codebase est difficile à comprendre. Donner un nom aux « patterns » aide un peu, mais au final il faut quand même beaucoup lire.
    Sur GitHub, les messages de commit par fichier donnent souvent l’impression de servir d’explication. Est-ce que ce serait peut-être plus utile ?

  • Dans tous les projets auxquels j’ai participé, pendant l’onboarding, on me présentait un diagramme d’architecture et une brève explication des composants.
    Du coup, je suis surpris que ce ne soit pas si courant dans l’open source.

    • Le problème, c’est justement « l’explication des composants ». Il faut que quelqu’un la fasse.
      Les projets open source n’ont pas de premier jour d’arrivée pour un employé, donc il n’y a pas non plus ce type d’introduction.
      À moins d’avoir énormément de temps, ce genre d’explication n’est pas très bon. On s’attend à ce qu’un employé mette plusieurs semaines avant d’être autonome, alors que nous, consultants en sécurité, nous recevons une explication totalement nouvelle toutes les deux semaines. Le problème, c’est que ces explications sont improvisées, non structurées, et que la personne qui parle, à cause de la malédiction de la connaissance, donne beaucoup de détails non pertinents.
      Le mieux serait probablement qu’une personne nouvellement arrivée dans le dépôt rédige cela une fois, puis qu’on ne fasse ensuite que la maintenance. À défaut, il vaut mieux que n’importe qui prenne une minute pour réfléchir à ce qu’il faut inclure ou exclure et l’écrive, plutôt que d’improviser une nouvelle explication à chaque fois. Comme l’auteur l’a dit, ce fichier doit expliquer l’architecture de haut niveau du projet et rester court. Tous les contributeurs réguliers devraient le lire, et plus il est court, moins il risque d’être invalidé par de futurs changements.
  • J’ai toujours trouvé que c’était une pratique très utile. Beaucoup de projets ont quelques fichiers centraux, ou bien des packages/modules, où se produisent la plupart des changements.
    Si un nouveau contributeur, ou un contributeur qui revient après longtemps, peut les assimiler rapidement, le temps de démarrage sur le projet diminue énormément.
    J’ai ajouté des fichiers d’architecture à des projets dans plusieurs entreprises où j’ai travaillé [0], [1], et les retours ont été bons. Ce n’est pas parfait, mais c’est mieux que de ne rien avoir.
    [0]: https://github.com/zapier/zapier-platform/pull/324
    [1]: https://github.com/stripe/stripe-cli/blob/master/ARCHITECTUR...

    • Est-ce qu’il existe un moyen automatique de voir ce genre de chose sur GitHub ? Par exemple une heatmap des changements de fichiers
  • Avant, j’aimais bien ces petits standards de documentation/diagrammes-as-code.
    README-driven development, ARCHITECTURE.md, ADR, arc42, C4, etc.
    Maintenant, je mets simplement un coffre Obsidian dans le dossier /docs du dépôt git.
    Au lieu d’utiliser le standard de quelqu’un d’autre, j’organise et je refactorise la documentation en continu dans Obsidian, comme je le ferais pour mes notes personnelles.
    Au début, je voulais utiliser un sous-ensemble commun de Markdown qui fonctionne à la fois avec le GFM de GitHub et avec Obsidian, mais j’ai abandonné. Désormais, j’utilise directement le Markdown façon Obsidian, y compris ses fonctionnalités spécifiques comme le plugin Dataview et les templates.
    Mermaid et LaTeX sont intégrés à Obsidian, et il existe aussi un plugin PlantUML. Pour les dessins/diagrammes visuels, j’utilise Canvas intégré, DrawIO et Excalidraw.