


Faire respecter à l'IA le style et les règles de modules d'un grand backend Java
Pour une IA dans un grand serveur Java de modules et de fournisseurs. Elle lit d'abord les points d'entrée, suit le style vérifié à la compilation et la version minimale de Java, déclare chaque module utilisé, vérifie dans le code avant d'affirmer et teste en local avant de pousser.
Pour utiliser ces règles d'IA
## Avant de modifier, comprendre comment modules et fournisseurs s'articulent
Un serveur de cette taille est assemblé à partir de modules, il n'est pas écrit comme une application unique. Une déclaration de module nomme le module et les interfaces de service qu'il expose ; un fournisseur implémente ces services avec une technologie précise ; les autres modules ne consomment que les interfaces déclarées. Les fournisseurs sont découverts via le mécanisme de chargement de services de la plateforme et suivent un cycle de vie fixe : une phase de préparation qui construit les objets et lit la configuration, puis une phase de démarrage qui active les services.
### Suivez le pipeline avant de toucher à une étape
Les collecteurs envoient la télémétrie sur la couche de transport, les plugins récepteurs l'analysent et la valident, le moteur d'analyse l'agrège au moyen des langages métier propres au projet, les plugins de stockage persistent le résultat et les plugins de requête le servent à l'interface. Un changement dans une étape exige généralement une contrepartie dans une autre.
### Lisez d'abord les points d'entrée
Avant toute modification, lisez la définition du module central, la classe de base du système de modules, les fichiers de grammaire des langages dédiés au domaine, le point d'entrée de l'application et la documentation d'architecture. Un nom ne vous dit pas comment une fonctionnalité fonctionne.
## Respecter le style de code vérifié automatiquement à la compilation
Ici le style est vérifié par la machine : une violation bloque la compilation au lieu d'ouvrir un débat. N'écrivez pas sur la sortie standard ; utilisez la façade de journalisation du projet. N'ajoutez pas d'annotations d'auteur. N'utilisez pas de caractères de tabulation, d'imports avec étoile, d'imports inutilisés ou redondants, d'instructions vides, ni plusieurs lignes vides consécutives. Gardez une seule instruction par ligne, gardez une espace après les virgules, les points-virgules et les conversions de type, et gardez des espaces autour des opérateurs.
### Motifs obligatoires
Annotez les méthodes redéfinies. Redéfinissez ensemble l'égalité et le hachage. Donnez à chaque balise de documentation de paramètre, de retour et d'exception une description réelle. Écrivez les constantes de type long avec une lettre de suffixe en majuscule. Placez la branche par défaut en dernier dans un switch. Respectez la longueur de fichier maximale et découpez tout fichier qui s'en approche.
### Nommage
Les constantes et les variables statiques s'écrivent en majuscules avec des traits de soulignement, les paramètres de type en majuscules, les types en casse Pascal, et les variables locales, les paramètres et les membres en casse camel. Préférez les fabriques de collections immuables et le processeur d'annotations du projet au code répétitif écrit à la main, et préférez les variables locales et les paramètres déclarés final.
### N'insérez pas de noms de classes pleinement qualifiés en ligne
Ajoutez un import et utilisez le nom court dans les déclarations de champs, les signatures de méthodes, les variables locales et les arguments génériques. Les seules exceptions acceptables sont une véritable collision de noms simples entre deux classes importées, et un unique lien de documentation où le nom court serait ambigu pour un lecteur.
### N'écrivez pas de méthodes de délégation d'une seule ligne
Une enveloppe dont le corps se contente de transmettre l'appel à une autre classe ajoute un saut sans valeur. Insérez l'appel sur le site d'utilisation ou appelez directement l'objet sous-jacent, y compris par référence de méthode.
### En-têtes de licence
Les fichiers source, de balisage et de configuration portent l'en-tête de licence du projet. Les formats qui ne peuvent pas contenir de commentaires sont exclus par la configuration de licence ; suivez cette configuration au lieu d'ajouter des en-têtes à la main là où ils n'ont pas leur place.
## Nommer classes et méthodes d'après leur rôle, pas par métaphore
Les classes et les méthodes sont nommées d'après leur fonction, pas d'après une métaphore abstraite. Préférez des verbes concrets comme charger, appliquer, désinscrire, compiler, vérifier, valider et annuler à des verbes métaphoriques comme ensemencer, hydrater, amorcer et préparer.
### Laissez le nom énoncer la tâche
Une classe qui charge des règles statiques est nommée d'après le chargement de règles statiques, pas d'après une image évocatrice. Un minuteur qui synchronise l'état de la base de données selon un calendrier est nommé d'après cette synchronisation, pas d'après un tic.
### Une métaphore est un signal qu'il faut découper
Si vous ne pouvez pas nommer une méthode sans recourir à une métaphore, c'est que la méthode en fait probablement trop. Découpez-la jusqu'à ce que chaque morceau ait un nom fonctionnel simple.
## Ne commenter que ce que le code n'explique pas lui-même
N'expliquez pas ce que le code énonce déjà. Ne commentez que là où lire le code ne suffit pas : un invariant qui n'est pas visible dans cette méthode, une contrainte d'ordre transversale, la raison d'être d'une branche non évidente, la raison pour laquelle un appel apparemment redondant est nécessaire. Si le code est clair, n'écrivez aucun commentaire.
### Reliez les logiques qui vivent séparément
Une vérification qui n'existe qu'à cause d'une garantie établie ailleurs mérite un renvoi d'une ligne vers cette garantie. Un contournement d'un défaut connu ailleurs mérite un lien vers ce défaut.
### Élaguez la documentation qui répète le code
La documentation d'une méthode décrit le contrat, pas le corps. Une justification de plusieurs paragraphes a sa place dans le document de conception, pas dans le fichier source.
## Utiliser les assertions du framework et demander avant de modifier un test
Utilisez toujours les méthodes d'assertion du framework de test. N'utilisez jamais l'instruction d'assertion intégrée au langage dans un test. Même là où l'exécuteur de tests active ces instructions, les assertions du framework sont la convention ailleurs dans la base de code, survivent à n'importe quelle configuration de l'exécuteur et produisent un échec structuré qui nomme la valeur réelle au lieu d'une erreur sans contexte.
### Corrigez les tests qui échouent, ne les modifiez pas en silence
Si des tests unitaires, d'intégration ou de bout en bout existants échouent, essayez de les corriger. Si un cas de test doit être modifié, ou si du code de test doit être supprimé, ce changement doit être contre-vérifié par un humain avant d'être appliqué : exposez la modification ou la suppression proposée et son raisonnement, et attendez une approbation explicite au lieu de modifier ou de supprimer le test vous-même.
### Adaptez le type de test à la portée
Les portées unitaire et d'intégration utilisent des motifs et des harnais différents. Prouvez le comportement à la portée où il se situe réellement plutôt que de dupliquer la même assertion à tous les niveaux.
## Écrire du code qui compile sur la version minimale de Java prise en charge
Un projet qui prend en charge plusieurs versions à support à long terme doit compiler et s'exécuter sur la plus ancienne, même quand la machine de compilation dispose d'un compilateur plus récent. Partez de la version minimale, pas de ce que votre éditeur accepte.
### Constructions à éviter quand la version minimale est ancienne
Les expressions switch en forme de flèche, l'opération terminale de flux qui renvoie directement une liste, les blocs de texte, les types record, le filtrage par motif dans une vérification de type et les types scellés sont tous plus récents qu'une base ancienne. Utilisez à la place un switch traditionnel avec des cas et des break explicites, un collecteur pour construire la liste, la concaténation de chaînes, une classe ordinaire avec des accesseurs générés, une conversion de type explicite après la vérification de type, et une classe ou une interface ordinaire.
### Constructions sans risque
Les fabriques de collections immuables, les méthodes optionnelles plus récentes, les expressions lambda, les références de méthodes et l'interface de flux elle-même sont disponibles sur une base ancienne et ne nécessitent aucun contournement.
### Vérifiez par la recherche, pas en vous fiant à la compilation
Recherchez chaque construction interdite dans l'arborescence source et confirmez l'absence de correspondance avant d'affirmer la compatibilité. Une compilation sur un compilateur plus récent ne les détectera pas pour vous.
## Garder les sous-modules et le code généré synchronisés avec la compilation
Les définitions de protocole et l'interface web peuvent vivre dans des sous-modules. Clonez toujours en incluant les sous-modules, et mettez-les à jour explicitement quand un changement de protocole l'exige. Un changement de protocole qui n'est pas reflété dans le pointeur de sous-module ne compilera chez personne d'autre.
### Générez avant d'analyser
Exécutez l'étape de compilation avant d'analyser du code généré, et installez le projet pour que le précompilateur et les classes générées soient exportés avant de lancer les tests. Ne modifiez jamais à la main les classes générées ; changez la définition qui les produit et recompilez.
### Recompilez tout le projet après des changements inter-modules
Si vous avez modifié plus de deux modules, ou si vous avez récupéré ou rebasé depuis le dépôt distant, compilez le projet entier plutôt que de sélectionner des modules individuels. Les compilations incrémentales d'un seul module peuvent laisser des archives obsolètes dans le dépôt local ou le répertoire de bibliothèques quand la taille de l'archive ne change pas mais que son contenu change, ce qui produit des défaillances à l'exécution très difficiles à tracer.
## Garder la documentation et le journal des modifications exacts et bien affichés
La documentation est rendue par un moteur markdown : réfléchissez donc à son apparence finale, pas seulement à la lecture de la source. Les chemins de fichiers relatifs sont valides et fonctionnent aussi bien dans le dépôt que sur le site de documentation ; continuez à les utiliser plutôt que des liens absolus. Mettez à jour le journal des modifications chaque fois qu'un comportement change.
### Gardez chaque puce du journal des modifications sur une seule ligne
Ne coupez pas une phrase sur plusieurs lignes source à l'intérieur d'une puce ; des sous-puces imbriquées sont acceptables car ce sont de véritables éléments de liste. Le journal des modifications devient le corps de la version publiée, et le moteur de rendu des versions transforme un simple saut de ligne de continuation en retour à la ligne : les puces coupées affichent donc des ruptures irrégulières au milieu des phrases sur la page de version, même si le site de documentation remet le texte au fil et masque le problème.
### Figez une proposition de conception une fois livrée
Quand l'implémentation d'une proposition de conception est livrée, synchronisez la proposition une fois avec ce qui a réellement été construit : chaque changement proposé rédigé au passé, sans aucune formulation restante de type travail en attente, travaux futurs, dépendance ouverte ou « vide jusqu'à » pour tout ce qui relève de sa portée. Après cette synchronisation, la proposition est figée. Les métriques, tableaux de bord et améliorations incrémentales ultérieurs vont dans la documentation vivante destinée aux exploitants. Seuls des suivis facultatifs réellement mineurs peuvent rester dans les travaux futurs ; jamais un changement important.
### Faites les renvois avec des liens d'ancrage
Renvoyez à une autre section par un lien d'ancrage markdown, jamais par un symbole de section ni par un simple numéro de section. Vérifiez que chaque ancre pointe vers un titre réel selon les règles de slug du site, car une ancre cassée est rendue silencieusement comme du texte brut.
## Déclarer chaque module que le code recherche
Toute recherche du service d'un autre module doit être adossée à une déclaration. Si du code demande au gestionnaire de modules de trouver un module, directement ou via une fonction utilitaire, le nom de ce module doit figurer dans la liste des modules requis du fournisseur. Une déclaration manquante ne provoque pas d'échec au démarrage ; elle déclenche une exception la première fois que ce chemin de code s'exécute. Envelopper l'appel dans un bloc catch large n'est pas un substitut : déclarez le module, et réservez la gestion défensive aux indisponibilités transitoires des fournisseurs. Lors de l'audit d'une branche, recherchez dans chaque module touché les recherches passant par le gestionnaire de modules et confirmez que chaque cible est déclarée.
### Mettez à jour toutes les implémentations, pas seulement la principale
Quand vous ajoutez un service à la liste des services d'un module central, mettez à jour toutes les implémentations de fournisseur de ce module, y compris les fournisseurs simulés utilisés par les outils autonomes et les harnais de test. Recherchez les sous-classes dans l'arborescence au lieu de supposer qu'il n'y en a qu'une. Le serveur principal n'est pas le seul conditionnement ; les outils autonomes démarrent avec des fournisseurs simulés et un sous-ensemble de modules, donc les changements apportés aux contrats des modules centraux doivent les atteindre aussi, sinon ces outils échouent au démarrage.
### Préférez le service déjà alimenté au module de coordination
Les modules récepteurs et analyseurs ne déclarent généralement pas le module de coordination de grappe : le rechercher directement déclenche donc une exception à l'exécution. Passez par le service de gestion des pairs du module central, que la couche de coordination alimente déjà et qui expose la liste de pairs dont la plupart des composants ont besoin. Si un module a réellement besoin de primitives de coordination, déclarez ce module explicitement.
### Ne faites pas transiter l'intention par des canaux détournés de type variable locale au thread
Faire passer l'intention d'un appelant par une variable locale au thread que du code en aval lit crée un couplage invisible entre des chemins de code éloignés, fuit à travers les passages de relais asynchrones tels que les exécuteurs et les boucles d'événements, et rend le comportement impossible à comprendre à partir d'une signature de méthode. Étendez plutôt l'interface : ajoutez un paramètre, une méthode ou une valeur de mode qui apparaît dans la signature, même si cela coûte plus de lignes. Les rares exceptions sont la propagation de contexte, pour laquelle toute l'industrie s'est standardisée sur une variable locale au thread, et les identités de sécurité imposées par un framework.
## Attendre que le changement de schéma atteigne tous les nœuds avant d'écrire des données
Quand les changements de schéma ou de métadonnées sont diffusés aux nœuds coordinateurs et propagés aux nœuds de données de façon asynchrone, un appel de définition revient dès que le coordinateur l'accepte, en portant un marqueur de révision, sans attendre les autres nœuds. Une écriture de données dont la définition ne s'est pas encore propagée est abandonnée sur le nœud qui l'exécute, journalisée et ignorée : une barrière est donc nécessaire.
### Attendez le seuil de révision
Après avoir émis un changement de définition, bloquez sur l'observateur de schéma du client jusqu'à ce que chaque nœud actif signale qu'il a appliqué au moins la révision retournée, avec un délai maximal, avant de libérer les écritures dépendantes. Une vérification de lecture après écriture sur le registre ne prouve pas la propagation.
### Traitez les suppressions et les stockages synchrones
Quand une suppression ne renvoie aucun marqueur de révision exploitable, repliez-vous sur l'appel dédié d'attente de suppression. Les stockages dont les instructions de définition sont synchrones sur le coordinateur n'ont besoin d'aucune barrière. Ne réintroduisez pas l'ancienne pratique consistant à interroger en boucle l'appel de recherche jusqu'à pouvoir relire votre propre écriture ; elle est antérieure à l'interface de barrière et a été remplacée.
### Vérifiez quelle bibliothèque cliente vous lisez
Les types de barrière et d'observateur peuvent se trouver dans une bifurcation cliente intégrée à l'arborescence plutôt que dans le client publié autonome. Leur absence du client publié ne prouve pas que l'interface a disparu.
## Vérifier dans le code et la documentation au lieu de deviner
Ne devinez ni ne spéculez jamais. Toute analyse doit être fondée sur le code source, la documentation ou un comportement observé. Lisez l'implémentation au lieu de supposer comment une fonctionnalité marche d'après son nom ou d'après la convention. Lisez la documentation du projet, les fichiers de consignes à l'intérieur des sous-modules et les fichiers readme avant de proposer une conception.
### Vérifiez la configuration et les options
Vérifiez quelles options et variables d'environnement existent réellement, quelles sont leurs valeurs par défaut et comment elles sont analysées, y compris toute convention de préfixe qui lie automatiquement les options aux variables d'environnement.
### Lisez les projets dont vous dépendez
Avant de supposer une capacité, lisez le code source et la documentation des dépendances et des projets compagnons concernés : les chartes de déploiement pour les champs pris en charge, l'infrastructure de test pour les options prises en charge, les bibliothèques clientes pour les appels disponibles. Si un projet compagnon est probablement déjà présent localement, demandez le chemin local, car chercher dans un clone local est bien plus rapide que de récupérer les fichiers un par un depuis une interface distante.
## Exécuter le code et les tests en local avant de compter sur l'intégration continue (CI)
Exécutez le code, démarrez le conteneur et lancez le test localement avant de pousser. L'intégration continue n'est pas un environnement d'essais et d'erreurs.
### Validez les chemins et les structures de répertoires
Vérifiez où les données atterrissent réellement au lieu de déduire un nom de répertoire d'un nom d'option ; une option de chemin racine crée fréquemment en dessous un sous-répertoire portant un autre nom.
### Validez la configuration générée ou modifiée
Après avoir modifié des fichiers de configuration, en particulier avec des éditeurs de flux ou des scripts, validez-les avec un vrai analyseur avant de valider vos changements. Une configuration corrompue provoque des défaillances silencieuses dans l'automatisation.
### Confirmez l'existence des images et des binaires
Vérifiez que l'image de conteneur est réellement publiée avant d'écrire une configuration de pipeline ou de bout en bout qui en dépend, et confirmez quels binaires, interpréteurs de commandes et répertoires existent à l'intérieur de l'image avant d'écrire des commandes qui les utilisent. La disponibilité d'une image dépend de l'achèvement des workflows de publication. Notez où résident les images : les images propres au projet peuvent se trouver sur un registre d'hébergeur de code avec des identifiants de commit complets comme étiquettes, tandis que les images officielles et tierces se trouvent sur le registre public avec des étiquettes conventionnelles.
## Pousser via le workflow de soumission du projet et l'automatisation approuvée
Utilisez le workflow de soumission dédié du projet pour valider et pousser vers une branche de revue. Il exécute des contrôles préalables tels que la compilation, la vérification du style et le contrôle des en-têtes de licence avant chaque poussée, et ouvre la demande de revue s'il n'en existe pas encore.
### Respectez la liste d'autorisation de l'automatisation
L'organisation peut imposer une liste d'autorisation pour les étapes d'automatisation tierces, exigeant que chacune soit épinglée à un identifiant de révision approuvé plutôt qu'à une étiquette de version. Si une revue est bloquée parce qu'une étape n'est pas autorisée, consultez la liste approuvée et mettez à jour les fichiers de workflow pour utiliser l'épinglage approuvé. Les étapes détenues par le fournisseur de la plateforme ou par l'organisation elle-même sont généralement autorisées sans épinglage.
### Dites ce qui manque plutôt que de deviner
Si vous ne trouvez pas le code source, si vous ne savez pas comment exécuter quelque chose, ou si le code ne rend pas la réponse évidente, posez la question au lieu de spéculer. Quand vous enquêtez sur un comportement à l'exécution, mettez en place un test local avec des données réelles et observez la sortie réelle au lieu de la prédire.
