Back to blog EN FR

Ce qui fait un concept de domaine

La plupart des modèles de domaine échouent non pas parce qu’ils sont techniquement faux, mais parce qu’ils capturent les mauvaises choses. Les équipes modélisent des classes, des services ou des tables et les appellent “concepts du domaine”. Ce n’en sont pas. Un concept du domaine, c’est ce que l’expert métier désigne lorsqu’il explique ce que le métier fait réellement. Si l’expert ne le reconnaît pas, il n’a pas sa place dans le modèle.

Prenez une plateforme de VTC. Une première tentative de modélisation produit : TripOrchestrationService, DriverLocationRepository, PaymentGatewayAdapter. Trois classes, mais zéro concept. Un expert métier chez Uber parlerait d’une Ride, d’un Driver, d’un Rider. Des mots que tout le monde utilise dans l’entreprise, de l’ops au produit en passant par l’engineering. Le reste n’est que du bruit.

La différence entre un modèle du domaine qui fonctionne et un qui pourrit tient à huit questions.

A-t-il un nom que les gens utilisent vraiment ?

Le nom est la poignée du concept. Si les experts métier ne l’emploient pas naturellement en conversation, c’est le mauvais nom. Un nom permet à une équipe de pointer vers une idée partagée sans devoir la réexpliquer à chaque fois.

Ride fonctionne. TripOrchestrationService non. Driver fonctionne. TransportProviderEntity non. Le test est simple : est-ce qu’un interlocuteur non technique comprendrait ce que vous voulez dire ? Si vous devez expliquer le nom, changez-le. Chez Uber, tout le monde dit “ride”, du passager qui ouvre l’app à l’agent support qui traite une réclamation.

A-t-il une raison d’exister ?

Un concept gagne sa place en servant un besoin, pas en décrivant un mécanisme. Sa raison d’être répond au pourquoi, pas au comment.

Ride existe pour transporter un passager d’un point A à un point B, au lieu de Car dispatch qui décrit un mécanisme. SurgeZone existe pour équilibrer l’offre et la demande en temps réel, au lieu de apply a surge multiplier to the fare. Si vous ne pouvez pas énoncer la raison d’être en une phrase sans mentionner l’implémentation, le concept est sans doute un artefact technique déguisé en concept métier.

Peut-on distinguer une instance d’une autre ?

L’identité détermine comment distinguer une instance d’une autre dans le temps, indépendamment de l’évolution de ses données. Un Driver identifié par un identifiant immuable restera le même chauffeur après avoir changé de numéro de téléphone, de véhicule ou de ville. La note fluctue, l’état de vérification évolue, le véhicule est remplacé. Mais l’identité du chauffeur reste le même.

Tout n’a pas besoin d’identité. Un FareBreakdown (tarif de base, prix au kilomètre, multiplicateur de surge, péages) n’a pas de cycle de vie. Si deux FareBreakdown ont des montants identiques, ils sont interchangeables. Cette distinction entre entité et valeur conditionne la façon dont vous stockez, comparez et raisonnez sur chaque instance.

Ne porte-t-il que ce dont il a besoin ?

L’état est la mémoire du concept : le minimum de données nécessaire pour supporter son comportement.

Un Driver doit retenir son verificationState, averageRating, totalRidesCompleted et son vehicle actuel. Pas besoin de retenir l’historique des itinéraires empruntés. Ces données appartiennent au module de géolocalisation, pas au chauffeur. Le Driver n’en a pas besoin pour décider de sa disponibilité, valider une vérification ou calculer sa note.

Si un attribut ne participe à aucune règle métier du concept, il appartient à un autre contexte ou n’appartient pas au modèle du domaine.

Fait-il quelque chose ?

Sans comportement, il n’y a pas de concept. Vous avez une donnée avec un nom.

Le comportement, ce sont des actions qui changent l’état. Une Ride vit à travers son cycle de vie :

  • request lance le matching et calcule une estimation tarifaire,
  • accept lie un chauffeur et démarre la navigation,
  • pickup commence la course,
  • complete déclenche le calcul du tarif et la capture du paiement,
  • cancel applique différentes règles selon qui annule et quand. Chaque action prend des entrées, applique des règles et fait transiter le concept vers un nouvel état.

Si vous ne pouvez pas énumérer les actions, demandez-vous si vous regardez un concept ou une structure de données.

Peut-on démontrer qu’il fonctionne ?

Un scénario prouve que le concept remplit sa raison d’être. On l’illustre avec un récit et non une liste de fonctionnalités. On se concentre sur une séquence d’actions qu’un expert peut vérifier contre sa compréhension métier.

Pour Ride :

Un passager demande une course, un chauffeur à proximité accepte dans les 15 secondes, se rend au point de prise en charge, démarre la course, la termine à destination, et le tarif est capturé automatiquement.

Pour Driver :

Un chauffeur soumet ses pièces d'identité, est vérifié, passe en ligne, reçoit des offres de course, et si sa note tombe sous 4.2 après 20 courses complétées, il est automatiquement suspendu.

Si le scénario ne tient pas, le concept ne tiendra pas non plus.

Qu’est-ce qui doit toujours être vrai ?

Les invariants protègent l’intégrité du concept. Ce sont les règles que le système doit garantir, quelle que soit la séquence d’actions :

  • Un chauffeur ne peut recevoir des offres que quand son état de vérification est verified et sa disponibilité est online.
  • Une offre de course expire après exactement 15 secondes.
  • Un même chauffeur ne peut pas être assigné à deux courses simultanément.
  • Un multiplicateur de surge ne peut pas dépasser 5.0x.

Ce ne sont pas des cas limites à traiter plus tard. C’est le contrat. Si l’on brise le contrat, le concept perd son sens.

Les préconditions gardent l’entrée d’une action. Les invariants gardent la sortie. Ensemble, ils enferment le concept dans un espace où il a toujours du sens.

Comment se compose-t-il avec les autres ?

Les concepts sont plus forts quand ils tiennent seuls. Mais dans un système réel, ils interagissent.

Quand Ride.complete() se déclenche, ça entraîne Payment.capture() pour facturer le passager et Driver.creditEarnings() pour créditer le chauffeur après commission. L’action d’un concept en provoque d’autres, comme une chaîne de réaction. Mais le couplage reste explicite : Ride ne sait pas comment le paiement fonctionne en interne. Elle sait seulement que la complétion déclenche une capture tarifaire. Quand le nombre d’annulations d’un Driver dépasse un certain seuil en 24 heures, cela déclenche une suspension de 30 minutes. Le module Ride signale l’événement, le module Driver applique la conséquence.

La composition va du couplage lâche (concepts en parallèle) au fortement coordonné (le cycle de vie d’un concept dépend de celui d’un autre). Le choix dépend du degré de couplage que la logique métier exige.

La checklist

Un concept qui passe les huit tests sera ancré dans le domaine :

  • nommé
  • justifié
  • identifiable
  • avec état
  • avec comportement
  • prouvé par scénario
  • contraint par des règles
  • composable

La compréhension partagée entre experts métier et développeurs est tout l’enjeu de la modélisation du domaine. Le code peut dériver. La documentation peut périmer. Mais un concept bien capturé résiste aux deux, parce que chaque personne impliquée peut la confronter à sa connaissance du domaine.

La plupart des échecs de modélisation ne sont pas techniques. Ce sont des échecs de capture. Le concept était là depuis le début, dans le vocabulaire de l’expert, dans les règles métier, dans les cas limites qui cassent la production. Le modèle n’a simplement jamais posé les bonnes questions.