Les accords sont une partie essentielle du développement de logiciels. Ils réduisent les coûts de développement et facilitent la vie des développeurs. Mais il y a un problème - ils compliquent souvent les choses parce qu'ils ne sont pas correctement documentés et transmis à travers l'équipe par le bouche à oreille, comme de vieux contes de fées. En se répandant, les accords changent. Soudain, de nouveaux détails apparaissent et les anciens disparaissent. À la fin, chaque membre de l'équipe a sa propre image d'accord dans la tête, et même cette image s'estompe parfois.
Pire encore, lorsque les équipes commencent à documenter ces accords, elles le font au hasard et créent souvent un gâchis de documents faiblement couplés, dont la moitié ne sont même pas à jour.
Dans cet article, je vais vous dire la bonne façon de documenter les accords, afin qu'ils vous aident.
Alors, comment pouvons-nous rendre les accords utiles ? Nous devons non seulement les documenter, mais aussi le faire pour que :
ils étaient faciles à utiliser;
le respect de ces accords demandait un minimum d'efforts ;
il serait facile de comprendre si ces accords sont toujours valables ;
il serait facile de comprendre pourquoi ces accords existent même;
idéalement - ils étaient automatisés.
On peut trouver de nombreuses façons de classer les accords. Je vais les diviser par leur niveau d'abstraction :
Les accords à différents niveaux nécessitent différentes manières de les documenter et apportent différents avantages. Jetons un coup d'œil à chaque niveau.
L'objectif de ces accords est de rendre le code uniforme, complet et lisible. Voici quelques exemples:
Nous utilisons des guillemets doubles au lieu de simples.
Nous n'appelons pas ENV directement à partir du code, sauf dans la classe Config
, où nous encapsulons ces appels dans des méthodes.
Les objets de service ont le suffixe Service
et un call
de méthode public.
Ces types d'accords sont créés pour réduire la charge cognitive du lecteur et l'aider à s'habituer plus rapidement à un code inconnu. Comme l'a dit Martin, le code est lu jusqu'à 10 fois plus qu'il n'est écrit.
Malgré votre opinion sur le framework Ruby on Rails - il a une convention over configuration
à la base, qui permet à tout développeur Rails d'ouvrir le projet de quelqu'un d'autre et de le naviguer immédiatement assez bien.
Alors comment documenter ces conventions ? Outil Linter ! S'il n'y a pas de règle de peluche appropriée, écrivez votre propre peluche. Presque tous les linters vous permettent de faire cela : voici un exemple en langage Go , et voici pour Ruby .
L'utilisation de linter pour de telles conventions vous apporte trois avantages :
Il n'est pas nécessaire qu'un développeur y pense - linter mettra en évidence chaque erreur et souvent même les corrigera pour vous.
Si vous utilisez des révisions de code dans votre équipe, vous libérez vos réviseurs de la réflexion sur ces choses et vous leur donnez plus de temps pour examiner des choses plus importantes.
Le développeur verra un problème au tout début du cycle de développement, il le corrigera donc immédiatement sans perdre de temps à revenir sur le contexte plus tard. Il devient moins cher de garder l'accord.
Un autre bonus : écrire une nouvelle règle de linter est une excellente formation pour un développeur junior. En accomplissant cette tâche, il en apprendra beaucoup sur l'analyse de code et la construction d'AST et comprendra plus profondément le langage.
Il s'agit d'un type d'accord de niveau supérieur qui vise à rendre votre architecture réfléchie, cohérente et uniforme. Quelques exemples :
Nous utilisons Python pour écrire des services réguliers et Elixir dans les parties les plus chargées du système.
Le backend renvoie les erreurs dans le format décrit.
Chaque service est tenu d'envoyer des métriques dans prometheus, sur le point de terminaison /metrics
, le port d'envoi des métriques est configuré par la variable d'environnement PROMETHEUS_PORT
.
De tels accords réduisent non seulement la charge cognitive, mais résolvent également trois autres problèmes :
Réduire les coûts d'exploitation. Si les services sont lancés de la même manière, avec le même format de logs, publiant les mêmes métriques, alors il est beaucoup plus facile de maintenir le service et de faire face aux incidents.
Réduire les coûts de conception. Le développeur n'a pas besoin de concevoir l'architecture à partir de zéro à chaque fois - vous avez pensé à l'avance, et maintenant il n'a besoin de concevoir qu'une fonctionnalité ou un service spécifique, sans se soucier des choses de base.
Réduire les coûts de communication. Si la réponse du serveur ou le format d'événement dans Kafka est prédéterminé, les développeurs n'ont pas besoin de discuter de leur interaction à chaque fois, ils peuvent simplement se référer à la convention.
De tels accords sont plus complexes, et je préfère les fixer en deux temps.
Étape 1 - Décrivez
Architecture Decision Record (ADR) est un outil de documentation de tels accords. Son charme est qu'il capture des méta-informations avec un accord : pourquoi un tel accord a été adopté ; quelles alternatives ont été discutées ; quand il a été révisé pour la dernière fois ; l'accord est-il toujours valable ?
Cela permet au nouveau membre de l'équipe de comprendre les raisons des décisions prises et de ne pas interroger les gens autour de lui.
L'ADR se compose de plusieurs blocs principaux :
Quel problème l'accord résout-il ?
Quelles options pour résoudre le problème ont été envisagées, et quels étaient leurs avantages et leurs inconvénients ?
Quelle option a finalement été choisie ?
Il peut y avoir des blocs supplémentaires - par exemple, le calcul des coûts de mise en œuvre.
Il est plus pratique de conserver l'ADR dans un système où l'on peut voir l'historique des changements et des discussions. Mon choix se porte sur Github et Notion, chacun avec ses avantages et ses inconvénients. L'avantage de Github est qu'il dispose d'un outil de révision et d'un historique des versions prêt à l'emploi. Notion peut être une bonne solution en raison de la commodité de travailler avec des bases de données et des balises. Et aussi - les non-développeurs peuvent facilement le gérer.
Si vous souhaitez démarrer avec ADR, je vous recommande de consulter le référentiel , où vous pouvez trouver différents modèles ADR et des exemples sur la façon de les utiliser.
Étape 2 - Automatiser
Les ADR sont plus difficiles à automatiser que les conventions au niveau du code : les linters de conception n'ont pas encore été inventés (quel dommage !). Néanmoins, il est possible de les automatiser partiellement, selon le type d'accord dont il s'agit.
Créez et mettez à jour des modèles de service pour les accords sur les langues, les bibliothèques et l'intégration des services dans l'infrastructure. Ensuite, le développeur n'écrira pas de nouveaux services à partir de zéro, mais le copiera plutôt à partir du modèle et recevra immédiatement le Dockerfile configuré, la publication des métriques, etc.
De même, vous pouvez créer des générateurs de classes dans une seule application. Supposons que vous vous soyez mis d'accord sur plusieurs couches applicatives (contrôleur => formulaire => objet service). Dans ce cas, vous pouvez créer une simple commande de console qui générera toutes les couches pour une nouvelle fonctionnalité à la fois.
Si vous vous êtes mis d'accord sur certains principes qui ne peuvent pas être automatisés de cette manière, vous pouvez organiser des listes de contrôle qui sont automatiquement ajoutées à une demande de fusion ou à une tâche dans le tracker ; ainsi, le développeur peut les parcourir rapidement avant de transmettre la tâche.
Il existe de nombreux accords de processus dans chaque entreprise, par exemple :
Description du fonctionnement de l'embauche dans l'entreprise.
Description du processus de déploiement de la version.
Exigence pour les revues de conception pour les tâches importantes.
Organiser une réunion d'équipe deux fois par semaine avec une discussion sur les tâches et les obstacles actuels.
Jusqu'à récemment, je n'avais pas pensé à documenter ces accords, bien qu'ils affectent considérablement le succès de l'entreprise. La documentation de ces accords apporte non seulement les avantages des types mentionnés ci-dessus, mais vous permet également de rationaliser les processus, de les transférer sur le plan visible et de réfléchir à leur opportunité.
J'ai eu l'idée de . Il a proposé un outil similaire à ADR - Process Decision Record (PDR). La seule différence est qu'au lieu de décisions architecturales, il décrit des décisions sur les processus. De plus, il a suggéré de mettre une "date de repenser" dans chaque PDR - une date à laquelle vous revenez au document pour voir s'il résout toujours vos problèmes de la meilleure façon, n mois après l'adoption (d'ailleurs, la même chose peut être faite avec les ADR).
Quant à l'automatisation, vous ne pouvez pas faire grand-chose. Vous pouvez automatiser certains processus en configurant un workflow dans Jira, en définissant des rappels pour les réunions ou en créant un bot qui prépare automatiquement une présentation des résultats de la semaine (je l'ai fait, cependant, dans une entreprise étrangère).
Mais souvent, vous ne pouvez pas vraiment automatiser les processus, et votre objectif principal est de les rendre plus faciles à suivre qu'à ne pas suivre. Néanmoins, documenter les accords sera toujours utile, même si vos processus sont déjà faciles à suivre - la formalisation et la rationalisation vous permettront de les améliorer.
La documentation et l'automatisation qui en découle sont bénéfiques : le temps consacré au développement diminue, les applications deviennent plus supportables et les processus deviennent plus intelligents.
On pourrait penser que tout cela est de la bureaucratie inutile parce que "nous sommes de bons gars - nous pouvons développer du code sans cela". Mais en fait, les ententes vous feront économiser beaucoup de temps et d'argent et protégeront les cellules nerveuses des employés. Bien sûr, vous n'avez pas besoin de traiter dans l'absolu et de rejeter tout ce qui va à l'encontre des accords - cela peut être un signe que l'accord doit être mis à jour ou que vous n'avez pas initialement pensé à certains de ses aspects.
Si vous n'avez pas encore commencé à documenter les accords dans votre équipe, passez des niveaux d'abstraction inférieurs aux niveaux supérieurs : commencez par les accords au niveau du code, puis au niveau de l'architecture, et ensuite seulement gérez le niveau des processus. La documentation des accords est une habitude à développer dans votre équipe, et commencer avec des concepts moins abstraits est beaucoup plus facile.
De plus, tous les types ne sont pas décrits dans l'article. Par exemple, vous pouvez documenter l'accord de conception sous forme de composants de bibliothèque.
Chaque nouveau type d'accord passe par les trois mêmes étapes :
Découvrez comment le documenter.
Découvrez comment l'automatiser.
Au fil du temps, assurez-vous qu'il économise plus de ressources qu'il n'en faut pour le conserver.
Et la dernière. Au cours du processus de documentation, il peut être constaté que certains des accords existants ne sont apparemment justifiés par rien, font perdre du temps à votre équipe et sont généralement nuisibles, mais vous y êtes déjà habitué. Dans ce cas, vous devez surmonter la barrière des habitudes dans l'esprit de l'équipe et convaincre votre équipe que le rejet des accords est parfois plus important que leur acceptation. Mais c'est une toute autre histoire.
Également publié ici .