Communitygithub.com

pedro-oscar/shorts-ai

Vocabulaire partagé pour concevoir des modules profonds. Utilisez-le lorsque vous souhaitez concevoir ou améliorer l'interface d'un module, trouver des opportunités d'approfondissement, décider où placer une jointure (seam), rendre le code plus testable ou navigable par l'IA, ou lorsque une autre compétence a besoin de ce vocabulaire.

Qu'est-ce que shorts-ai ?

Cette compétence établit un vocabulaire précis et cohérent pour la conception de modules logiciels profonds, en s'appuyant sur les concepts clés de module, interface, profondeur (depth), jointure (seam) et adaptateur. Elle aide les développeurs à créer des interfaces petites mais riches en comportement, améliorant ainsi la testabilité, la localité des changements et l'effet de levier pour les appelants. La compétence est indépendante de la plateforme et fournit des définitions strictes à utiliser dans la conception de code, les revues et les refactorings. Elle inclut des principes directeurs, des tests de suppression, des règles pour l'introduction de joints, ainsi que des conseils pratiques pour la testabilité (accepter les dépendances, retourner des résultats, réduire la surface d'interface).

Compatible avec~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/pedro-oscar/shorts-ai/tree/HEAD/.claude/skills/codebase-design

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Conception du code source

Concevez des modules profonds : beaucoup de comportement derrière une petite interface, placée à une jointure nette, testable via cette interface. Utilisez ce langage et ces principes partout où du code est conçu ou restructuré. L'objectif est l'effet de levier pour les appelants, la localité pour les mainteneurs et la testabilité pour tout le monde.

Glossaire

Utilisez ces termes exactement : ne remplacez pas par « composant », « service », « API » ou « frontière ». Un langage cohérent est le cœur du sujet.

Module : tout ce qui possède une interface et une implémentation. Volontairement indépendant de l'échelle : une fonction, une classe, un paquetage ou une tranche traversant plusieurs niveaux. À éviter : unité, composant, service.

Interface : tout ce qu'un appelant doit connaître pour utiliser correctement le module : la signature de type, mais aussi les invariants, les contraintes d'ordre, les modes d'erreur, la configuration requise et les caractéristiques de performance. À éviter : API, signature (trop étroits, ils ne désignent que la surface au niveau des types).

Implémentation : ce qui se trouve à l'intérieur d'un module, son corps de code. Distinct de Adaptateur : une chose peut être un petit adaptateur avec une grande implémentation (un dépôt Postgres) ou un grand adaptateur avec une petite implémentation (un faux en mémoire). Utilisez « adaptateur » lorsque la jointure est le sujet ; « implémentation » autrement.

Profondeur (depth) : l'effet de levier au niveau de l'interface. La quantité de comportement qu'un appelant (ou un test) peut exercer par unité d'interface qu'il doit apprendre. Un module est profond lorsqu'une grande quantité de comportement se cache derrière une petite interface, peu profond lorsque l'interface est presque aussi complexe que l'implémentation.

Jointure (seam) (Michael Feathers) : un endroit où vous pouvez modifier le comportement sans éditer à cet endroit ; l'emplacement où réside l'interface d'un module. Où placer la jointure est une décision de conception en soi, distincte de ce qui se trouve derrière. À éviter : frontière (surchargé par le contexte délimité de DDD).

Adaptateur (adapter) : une chose concrète qui satisfait une interface à une jointure. Décrit un rôle (quel emplacement il remplit), pas une substance (ce qu'il contient).

Effet de levier (leverage) : ce que les appelants obtiennent de la profondeur. Plus de capacité par unité d'interface apprise. Une implémentation se rémunère sur N sites d'appel et M tests.

Localité (locality) : ce que les mainteneurs obtiennent de la profondeur. Les changements, les bogues, la connaissance et la vérification se concentrent en un seul endroit plutôt que de se propager chez les appelants. Corrigez une fois, corrigé partout.

Profond vs peu profond

Module profond = petite interface + beaucoup d'implémentation :

┌─────────────────────┐
│   Petite Interface  │  ← Peu de méthodes, paramètres simples
├─────────────────────┤
│                     │
│ Implémentation      │  ← Logique complexe cachée
│ Profonde            │
│                     │
└─────────────────────┘

Module peu profond = grande interface + peu d'implémentation (à éviter) :

┌─────────────────────────────────┐
│       Grande Interface          │  ← Beaucoup de méthodes, paramètres complexes
├─────────────────────────────────┤
│  Implémentation fine            │  ← Transmet simplement
└─────────────────────────────────┘

Lors de la conception d'une interface, demandez-vous :

  • Puis-je réduire le nombre de méthodes ?
  • Puis-je simplifier les paramètres ?
  • Puis-je cacher plus de complexité à l'intérieur ?

Principes

  • La profondeur est une propriété de l'interface, pas de l'implémentation. Un module profond peut être composé intérieurement de petites parties mockables et interchangeables ; elles ne font simplement pas partie de l'interface. Un module peut avoir des jointures internes (privées à son implémentation, utilisées par ses propres tests) ainsi que la jointure externe à son interface.
  • Le test de suppression. Imaginez supprimer le module. Si la complexité disparaît, c'était une simple passe. Si la complexité réapparaît chez N appelants, il méritait sa place.
  • L'interface est la surface de test. Les appelants et les tests traversent la même jointure. Si vous voulez tester au-delà de l'interface, le module a probablement la mauvaise forme.
  • Un adaptateur signifie une jointure hypothétique. Deux adaptateurs signifient une jointure réelle. N'introduisez pas de jointure à moins que quelque chose ne varie réellement à travers elle.

Conception pour la testabilité

Les bonnes interfaces rendent le test naturel :

  1. Acceptez les dépendances, ne les créez pas.

    // Testable
    function processOrder(order, paymentGateway) {}
    
    // Difficile à tester
    function processOrder(order) {
      const gateway = new StripeGateway();
    }
    
  2. Retournez des résultats, ne produisez pas d'effets de bord.

    // Testable
    function calculateDiscount(cart): Discount {}
    
    // Difficile à tester
    function applyDiscount(cart): void {
      cart.total -= discount;
    }
    
  3. Petite surface. Moins de méthodes = moins de tests nécessaires. Moins de paramètres = configuration de test plus simple.

Relations

  • Un Module a exactement une Interface (la surface qu'il présente aux appelants et aux tests).
  • La Profondeur est une propriété d'un Module, mesurée par rapport à son Interface.
  • Une Jointure est l'endroit où réside l'Interface d'un Module.
  • Un Adaptateur se trouve à une Jointure et satisfait l'Interface.
  • La Profondeur produit un Effet de levier pour les appelants et une Localité pour les mainteneurs.

Cadres rejetés

  • Profondeur comme ratio lignes d'implémentation / lignes d'interface (Ousterhout) : récompense le gonflement de l'implémentation. Nous utilisons la profondeur comme effet de levier.
  • « Interface » comme mot-clé interface de TypeScript ou méthodes publiques d'une classe : trop étroit : l'interface inclut ici tout fait qu'un appelant doit connaître.
  • « Frontière » : surchargé par le contexte délimité de DDD. Dites jointure ou interface.

Aller plus loin

  • Approfondir un groupe étant données ses dépendances, voir DEEPENING.md : catégories de dépendances, discipline de jointure, et tests de remplacement plutôt que de superposition.
  • Explorer des interfaces alternatives, voir DESIGN-IT-TWICE.md : lancer des sous-agents parallèles pour concevoir l'interface de plusieurs façons radicalement différentes, puis comparer sur la profondeur, la localité et le placement de la jointure.

Individual skills in this repo

This repo contains 3 individual skills — each has its own dedicated page.

Skills associés