Diagramme de Code C4 (niveau 4) : quand en avez-vous besoin, et quand pas - Archyl Blog

Le diagramme de code (modèle C4 niveau 4) montre les classes, interfaces et fonctions à l'intérieur d'un composant. La plupart des équipes devraient s'en passer -- mais pas toujours. Ce guide explique quand le niveau 4 du modèle C4 vaut le coup, quand un diagramme de classes UML est de l'effort perdu, et comment la génération automatique change la donne.

Diagramme de Code C4 (niveau 4) : quand en avez-vous besoin, et quand pas

Le diagramme de Code est le niveau le plus mal compris du modèle C4. C'est le niveau que la plupart des équipes sautent, le niveau que Simon Brown lui-même décrit comme optionnel, et pourtant c'est aussi celui qui génère le plus de questions : "Faut-il vraiment dessiner nos classes ?" "Ce n'est pas juste de l'UML ?" "Qui maintient ça quand le code change ?"

La réponse courte : la plupart du temps, vous n'avez pas besoin d'un diagramme de code C4. La réponse longue est plus intéressante, parce que les cas où le niveau 4 est rentable sont précisément ceux où les équipes perdent le plus de temps sans lui -- algorithmes denses, domaines réglementés, et onboarding dans du code que plus personne ne comprend entièrement.

Ce guide couvre ce qu'un diagramme de code C4 montre réellement, pourquoi le dessiner à la main est presque toujours une erreur, les situations précises où le modèle C4 niveau 4 mérite sa place, et comment la génération automatique renverse complètement le calcul coût-bénéfice.

Si vous découvrez le modèle C4, commencez par notre guide complet du modèle C4 -- cet article suppose que vous connaissez les quatre niveaux.

Qu'est-ce qu'un diagramme de code C4 ?

Le diagramme de Code est le niveau 4 du modèle C4 -- le niveau de zoom le plus profond. Là où le diagramme de Components (niveau 3) montre les grands blocs à l'intérieur d'un container, le diagramme de code zoome dans un seul composant et révèle ses détails d'implémentation :

  • Les classes et leurs relations (héritage, composition, dépendance)
  • Les interfaces et les types qui les implémentent
  • Les fonctions et méthodes, avec leurs signatures clés
  • Les structures de données : entités, value objects, DTOs

En pratique, un diagramme C4 niveau 4 prend généralement la forme d'un diagramme de classes UML ou d'un diagramme entité-relation. Le modèle C4 ne prescrit aucune notation à ce niveau -- il délègue explicitement aux standards existants, parce que le problème de dessiner des classes a été résolu il y a des décennies.

Deux propriétés définissent le niveau Code :

  1. Le périmètre : un seul composant. Un diagramme de code ne couvre jamais un container entier, encore moins un système. Il ouvre exactement un composant -- l'OrderRepository, le PaymentService -- et montre ce qu'il y a dedans.
  2. La granularité : de vrais symboles du code. Chaque boîte d'un diagramme de code correspond à une classe, une interface ou une fonction réelle dans les sources. Il n'y a plus aucune abstraction. C'est le niveau où le diagramme et le code sont censés être la même chose.

Cette seconde propriété est précisément la raison pour laquelle le niveau 4 est si souvent sauté, comme on va le voir. (Pour une référence rapide, consultez l'entrée diagramme de code de notre glossaire.)

La recommandation de Simon Brown lui-même : ne le dessinez pas

Voici la partie qui surprend ceux qui découvrent le modèle C4 : son créateur déconseille de créer des diagrammes de code à la main. La position de Simon Brown est que le niveau 4 est optionnel, et que lorsque vous en avez besoin, il devrait être généré à la demande depuis le code source -- par votre IDE, par un outil de documentation, ou par tout ce qui lit le code réel -- plutôt que dessiné et maintenu manuellement.

Le raisonnement est difficile à contester :

  • Le code change en permanence. Un diagramme de classes dessiné à la main reste exact à peu près le temps qu'il faut pour merger la prochaine pull request. Chaque renommage, chaque méthode extraite, chaque nouveau champ le rend un peu plus faux.
  • L'information existe déjà. Contrairement à un diagramme de Containers -- qui capture des décisions qui ne vivent dans la tête de personne ni dans aucun fichier unique -- un diagramme de code duplique ce que le code source énonce déjà avec précision.
  • Les outils font ça mieux. Les IDE modernes (IntelliJ, Visual Studio et compagnie) génèrent des diagrammes de classes depuis le code en quelques secondes. Ils sont toujours exacts parce qu'ils sont dérivés, pas dessinés.

La position par défaut de toute équipe adoptant le C4 devrait donc être : modélisez les niveaux 1 à 3, générez le niveau 4 quand nécessaire. Les diagrammes de Contexte, de Containers et de Components capturent une connaissance qui n'est pas dans le code. Le niveau Code est le code.

Quand un diagramme de code C4 vaut vraiment le coup

"À sauter en général" ne veut pas dire "à sauter toujours". Il existe de vraies situations où une vue au niveau du code mérite sa place dans votre documentation.

1. Algorithmes complexes et conceptions sophistiquées

Certains composants implémentent une logique réellement difficile à suivre en lisant les fichiers de haut en bas : un moteur de tarification avec des stratégies chaînées, une machine à états gouvernant le cycle de vie des commandes, un parseur avec une hiérarchie de visiteurs profonde. Quand la structure du code est l'insight -- quand comprendre quelle classe délègue à quelle autre est tout le combat -- un diagramme de code compresse des heures de lecture en une seule image.

Le test : si un ingénieur senior a besoin d'un tableau blanc pour expliquer le composant à un autre ingénieur senior, ce croquis au tableau blanc est un diagramme de code qui attend d'être capturé.

2. Domaines réglementés et audités

Dans la finance, la santé, l'aéronautique et les autres industries réglementées, les auditeurs exigent souvent une documentation au niveau de l'implémentation : quelle classe manipule les données bancaires, où le chiffrement est appliqué, comment la piste d'audit est écrite. Ici, un diagramme de niveau 4 n'est pas un confort -- c'est une pièce justificative. Même chose pour les revues de sécurité et le threat modeling, où le flux des données à travers des classes précises compte.

3. Onboarding dans du code dense et ancien

Les composants legacy chargés d'années de décisions accumulées sont brutaux pour les nouveaux arrivants. Un diagramme de code des trois ou quatre composants les plus effrayants de votre codebase -- ceux où la connaissance tribale est concentrée -- peut réduire drastiquement le temps d'onboarding. Les nouveaux développeurs voient la forme du composant avant de plonger dans ses 8 000 lignes.

4. Documenter des contrats publics et des design patterns

Si un composant expose une surface d'API sur laquelle d'autres équipes construisent, ou implémente un pattern (Strategy, Observer, ports-et-adaptateurs hexagonaux) où la structure est la documentation, une vue au niveau du code rend le contrat explicite.

Quand vous n'en avez pas besoin (c'est-à-dire la plupart du temps)

Soyons honnêtes sur les cas inverses, parce qu'ils couvrent la majorité des composants de n'importe quel système :

  • Le code est lisible. Un composant bien nommé avec des packages clairs n'a pas besoin de diagramme. L'arborescence est le diagramme.
  • Le niveau 3 répond déjà à la question. Si quelqu'un demande "comment le service commandes parle-t-il aux paiements ?", c'est une question de diagramme de Components. Dessiner des classes ajoute du bruit, pas du signal.
  • Le composant est du CRUD basique. Un handler, un service, un repository, un modèle. Tout le monde a vu cette forme mille fois. La documenter au niveau des classes ne documente rien.
  • Personne n'a rien demandé. La documentation doit répondre à des questions que les gens se posent réellement. Si personne n'a jamais eu besoin d'une vue au niveau des classes d'un composant, en créer une est de l'effort dépensé pour l'étagère.

Le principe directeur de l'approche C4 s'applique ici avec toute sa force : chaque diagramme que vous créez est un diagramme que vous devez maintenir. Aux niveaux 1 à 3, ce coût de maintenance vous achète une connaissance qui n'existe nulle part ailleurs. Au niveau 4, il vous achète généralement une copie un peu plus jolie et un peu plus périmée de votre code source.

Comment la génération automatique change la donne

Tout ce qui précède suppose que quelqu'un doit dessiner et maintenir le diagramme. C'est cette hypothèse qui rendait le conseil de Simon Brown -- "sautez-le ou générez-le" -- incontestable : le coût d'un niveau 4 manuel ne justifiait presque jamais le bénéfice.

L'automatisation supprime le côté coût de l'équation. La découverte par IA d'Archyl analyse votre repository connecté et extrait les éléments au niveau du code -- classes, interfaces et fonctions -- directement depuis les sources, en les rattachant aux bons composants de votre modèle C4. Au lieu qu'un développeur dessine PaymentService et ses collaborateurs dans un outil de diagramme, le modèle est alimenté par ce qui existe réellement dans la codebase, et il reste connecté au repository dont il provient.

La question passe alors de "le niveau 4 vaut-il la peine d'être maintenu ?" à "le niveau 4 vaut-il la peine d'exister ?" -- une barre bien plus facile à franchir. Quand la vue au niveau du code est générée et rafraîchie plutôt que dessinée à la main :

  • Elle ne ment jamais, parce qu'elle dérive des sources et non du souvenir que quelqu'un a des sources.
  • Elle est navigable en contexte : vous descendez du système au container, au composant, puis au code dans un seul modèle, au lieu de chercher un PNG dans un wiki.
  • Les cas qui étaient "rentables malgré le coût" (audits, onboarding, composants complexes) deviennent trivialement rentables, et les cas limites deviennent gratuits.

Vous gardez votre jugement sur les composants qui méritent de l'attention au niveau 4 -- une vue générée d'un composant CRUD trivial reste du bruit. Mais le mode d'échec change : on passe de "diagramme périmé qui induit l'équipe en erreur" à "vue inutilisée qui ne coûte rien".

Un exemple concret : à l'intérieur d'un composant de traitement des paiements

Rendons cela concret. Supposons que votre diagramme de Components (niveau 3) montre un composant PaymentProcessor dans votre container API backend. En zoomant dedans au niveau 4, on pourrait voir :

[PaymentService (interface)]
  ├── ProcessPayment(order, method) -> PaymentResult
  └── RefundPayment(paymentID, amount) -> RefundResult

[StripePaymentService] ──implémente──> [PaymentService]
[StripePaymentService] ──utilise──> [StripeAdapter] : encapsule le SDK Stripe
[StripePaymentService] ──utilise──> [RetryPolicy] : backoff exponentiel, 3 tentatives
[StripePaymentService] ──utilise──> [PaymentRepository] : persiste les enregistrements de paiement

[StripeAdapter] ──traduit──> [PaymentResult] : convertit les réponses Stripe en types du domaine
[RetryPolicy] ──lève──> [PaymentFailedError] : après épuisement des tentatives
[PaymentRepository] ──persiste──> [Payment (entité)]

Remarquez ce que cette vue révèle et que le niveau 3 ne peut pas montrer :

  • Où est la couture pour les tests ? PaymentService est une interface ; les tests peuvent substituer un faux sans toucher à Stripe.
  • Où brancherait-on un second prestataire ? Un PaypalPaymentService implémentant la même interface -- la structure rend le point d'extension évident.
  • Que se passe-t-il en cas d'échec ? La classe RetryPolicy possède le comportement de backoff ; PaymentFailedError est le chemin d'escalade. Un auditeur qui demande "que se passe-t-il quand un débit échoue ?" obtient sa réponse depuis le diagramme.
  • Qu'est-ce qui touche la base de données ? Uniquement PaymentRepository. Le flux des données bancaires est traçable, ce qui compte énormément dans un composant soumis à PCI.

Voilà un composant où le niveau 4 se rentabilise : il est financièrement sensible, la gestion des échecs n'est pas évidente, et plusieurs classes collaborent selon un pattern délibéré. Comparez avec, disons, un UserProfileHandler qui lit et écrit un profil -- le dessiner au niveau des classes ne vous apprendrait rien que l'arborescence ne dit déjà.

Erreurs courantes avec le niveau 4 du C4

Maintenir des diagrammes de classes à la main

L'échec classique. Un ingénieur motivé dessine de magnifiques diagrammes de classes pour toute la codebase ; six mois plus tard, ils décrivent une codebase qui n'existe plus, et désormais ils induisent activement en erreur. Si un diagramme de code n'est pas généré depuis les sources -- ou au minimum régénéré régulièrement -- considérez-le comme périmé le jour où il est dessiné.

Documenter les getters, setters et le boilerplate

Un diagramme de code qui liste chaque accesseur, chaque surcharge de constructeur et chaque méthode utilitaire a le même problème qu'une carte à l'échelle 1:1. Incluez les éléments qui portent une intention de conception -- les interfaces, les collaborations clés, les méthodes qui définissent le contrat -- et omettez le cérémonial. Les vues générées doivent être filtrées, pas déversées en vrac.

Utiliser le niveau 4 là où le niveau 3 suffit

Si votre "diagramme de code" montre des choses comme "le contrôleur appelle le service qui appelle le repository", vous avez dessiné un diagramme de Components avec des boîtes en forme de classes. Repliez-le au niveau 3. Réservez le niveau 4 aux composants dont la structure interne est la partie intéressante.

Dessiner tout le container au niveau des classes

Un diagramme de 200 classes couvrant un service entier viole la hiérarchie C4 et est de toute façon illisible. Un diagramme de code couvre un composant. Si vous ne pouvez pas le délimiter aussi strictement, les frontières de composants de votre diagramme de niveau 3 méritent probablement d'être repensées.

Considérer le niveau 4 comme obligatoire pour une documentation "complète"

Certaines équipes adoptent le C4 avec une mentalité de checklist : quatre niveaux, donc quatre jeux de diagrammes. Le résultat : de l'effort gaspillé et du ressentiment envers toute la pratique. Le C4 est explicite : le niveau 4 est optionnel. Trois niveaux bien maintenus battent quatre niveaux qui pourrissent, à chaque fois.

FAQ

Le niveau 4 du C4, c'est juste un diagramme de classes UML ?

En grande partie, oui -- et c'est voulu. Le modèle C4 ne définit pas sa propre notation pour le niveau Code ; il recommande de réutiliser les notations existantes, et le diagramme de classes UML est le choix le plus courant (les diagrammes entité-relation conviennent aux composants centrés sur les données). Ce que le C4 ajoute, c'est le périmètre et le contexte : le diagramme de classes décrit exactement un composant, et ce composant s'inscrit dans une hiérarchie navigable de diagrammes de containers et de systèmes. Un diagramme de classes UML isolé flotte dans le vide ; un diagramme de code C4 a une adresse.

Faut-il créer un diagramme de code pour chaque composant ?

Non. La plupart des composants sont assez simples pour que le code source soit la meilleure documentation. Réservez le niveau 4 aux composants algorithmiquement complexes, sensibles en termes de sécurité ou de conformité, ou notoirement difficiles pour l'onboarding. Si la documentation est générée automatiquement, le coût d'une couverture plus large chute -- mais l'attention reste finie, donc choisissez ce que vous mettez en avant.

Comment garder un diagramme de code à jour ?

En ne le maintenant pas à la main. Générez-le : depuis votre IDE à la demande, depuis un outil de documentation en CI, ou depuis une plateforme comme Archyl qui extrait les classes, interfaces et fonctions de votre repository pendant la découverte par IA et garde le niveau code rattaché à votre modèle de composants. Tout processus qui repose sur un humain se souvenant de mettre à jour un diagramme de classes après un refactoring échouera.

Quelle est la différence entre un composant et un élément de code dans le C4 ?

Un composant (niveau 3) est un regroupement logique avec une responsabilité unique -- "la partie qui gère les paiements" -- et peut couvrir plusieurs classes et fichiers. Un élément de code (niveau 4) est un symbole réel des sources : une classe, une interface ou une fonction précise. Les composants sont des abstractions que vous choisissez ; les éléments de code sont des faits que le compilateur impose.

En résumé

Le diagramme de code C4 est le niveau à sauter par défaut et à déployer délibérément. Les niveaux 1 à 3 capturent une connaissance architecturale qui n'existe nulle part ailleurs ; le niveau 4 reflète ce que le code dit déjà, et ne mérite donc sa place que lorsque la structure elle-même est la difficulté -- algorithmes complexes, composants réglementés, legacy dense -- et idéalement lorsqu'il est généré plutôt que dessiné.

Si vous voulez des vues au niveau du code sans la taxe de maintenance, connectez un repository à Archyl et laissez la découverte par IA extraire automatiquement les classes, interfaces et fonctions dans votre modèle C4. Vous obtenez la profondeur quand vous en avez besoin, et plus personne n'a jamais à redessiner un diagramme de classes.


Envie de remonter d'un niveau ? Lisez le guide du diagramme de Components C4, révisez avec le guide complet du modèle C4, ou explorez la page modèle C4. Prêt à essayer ? Démarrez gratuitement avec Archyl.