Context Scope

Construire un Langage Omniprésent : De l'Atelier au Code

📅 Publié le 20 December 2024 • ⏱️ 5 min de lecture

Construire un Langage Omniprésent : De l'Atelier au Code

L'Ubiquitous Language (langage omniprésent) est sans doute l'un des concepts les plus sous-estimés du Domain-Driven Design. Pourtant, c'est la fondation sur laquelle repose toute implémentation DDD réussie.

Voici une méthode éprouvée pour construire et maintenir un langage partagé efficace.

Pourquoi l'Ubiquitous Language est crucial

Le problème de la traduction

Dans la plupart des projets, on observe un phénomène de "traduction" permanente :

  • Les experts métier parlent en termes business
  • Les analystes traduisent en spécifications
  • Les développeurs retraduisent en code

Chaque traduction introduit des distorsions et des malentendus.

L'objectif : Un langage unique

L'Ubiquitous Language vise à créer un vocabulaire partagé qui :

  • Élimine les ambiguïtés
  • Facilite la communication
  • Se reflète directement dans le code
  • Évolue avec la compréhension du domaine

Atelier de découverte : Event Storming collaboratif

Préparation de l'atelier

Participants essentiels :

  • Experts métier (2-3 maximum)
  • Product Owner/Manager
  • Architecte technique
  • Développeurs seniors (2-3)

Matériel nécessaire :

  • Mur libre de 3-4 mètres
  • Post-its de couleurs différentes
  • Marqueurs épais
  • Timer pour les sessions

Phase 1 : Big Picture Event Storming

🟠 Événements métier
🟦 Commandes
🟡 Acteurs/Utilisateurs
🟪 Systèmes externes
🟢 Read Models/Vues
🔴 Points chauds/Problèmes

Règles de l'atelier :

  1. Pas de débat pendant le brainstorming - On colle d'abord, on discute après
  2. Utiliser des verbes au passé pour les événements
  3. Être spécifique - "Commande créée" plutôt que "Quelque chose s'est passé"
  4. Capturer les désaccords avec des post-its rouges

Phase 2 : Identification des termes ambigus

Exemple concret d'ambiguïté découverte :

"Commande" peut signifier :
- 📋 Purchase Order (bon de commande du client)
- 📦 Work Order (ordre de fabrication interne)  
- 🚚 Delivery Order (bon de livraison)

💡 Résolution : 
- CustomerOrder
- ProductionOrder  
- ShipmentOrder

Phase 3 : Définition collaborative

Pour chaque terme identifié, créez une définition collaborative :

Template de définition :

Terme: CustomerOrder
Définition: Une demande d'achat formalisée émise par un client 
           pour l'acquisition de produits spécifiques
Synonymes: Purchase Order, Commande Client
Contexte: Utilisé dans le processus de vente depuis la création 
          jusqu'à la facturation
Exemple: "CustomerOrder #12345 contient 3 widgets à 50€ chacun"

De l'atelier au code : Mise en pratique

Règle fondamentale : Le code reflète le langage

// ❌ Code qui ne reflète pas l'Ubiquitous Language
public class Order 
{
    public List<Item> Items { get; set; }
    public decimal Price { get; set; }
    public string Status { get; set; }
}

// ✅ Code qui reflète l'Ubiquitous Language
public class CustomerOrder 
{
    public OrderNumber Number { get; private set; }
    public List<OrderLine> Lines { get; private set; }
    public Money TotalAmount { get; private set; }
    public OrderStatus Status { get; private set; }
    
    public void AddOrderLine(Product product, Quantity quantity)
    {
        // Logique métier avec les termes du domaine
        if (Status != OrderStatus.Draft)
            throw new OrderNotModifiableException(
                "Cannot modify a confirmed CustomerOrder");
    }
}

Captures des règles métier

// Les invariants utilisent le vocabulaire métier
public class CustomerOrder
{
    public void ConfirmOrder()
    {
        if (Lines.Count == 0)
            throw new EmptyOrderCannotBeConfirmedException();
            
        if (!Customer.HasValidCreditLimit(TotalAmount))
            throw new InsufficientCreditLimitException();
            
        Status = OrderStatus.Confirmed;
        RaiseEvent(new CustomerOrderConfirmed(Number, Customer.Id));
    }
}

Évolution et maintenance du langage

Glossaire vivant

Maintenez un glossaire partagé qui évolue :

# Glossaire Domaine E-commerce

## CustomerOrder (Commande Client)
**Définition :** Demande d'achat formalisée par un client
**Statuts possibles :** Draft, Confirmed, Cancelled, Fulfilled
**Règles métier :**
- Une CustomerOrder en statut Confirmed ne peut plus être modifiée
- Le montant total ne peut pas dépasser la limite de crédit du client

## OrderLine (Ligne de Commande)  
**Définition :** Article individuel dans une CustomerOrder
**Propriétés :** Product, Quantity, UnitPrice, LineTotal
**Règles métier :**
- La quantité doit être positive
- Le prix unitaire doit correspondre au tarif actuel du produit

Sessions de refinement régulières

Fréquence recommandée : Toutes les 2-3 sprints

Format de session (1h) :

  1. Review des nouveaux termes (15 min)
  2. Clarification des ambiguïtés (30 min)
  3. Mise à jour du glossaire (15 min)

Détection des dérives

Signaux d'alarme :

  • Les développeurs utilisent des termes différents du glossaire
  • Les tests utilisent un vocabulaire différent
  • Les conversations avec le métier nécessitent des "traductions"

Techniques avancées

Domain Storytelling

Complément à l'Event Storming pour capturer les processus :

👤 Customer ➜ 📝 creates ➜ 🛒 CustomerOrder
🛒 CustomerOrder ➜ 📧 triggers ➜ 📨 OrderConfirmationEmail  
👨‍💼 SalesRep ➜ ✅ validates ➜ 🛒 CustomerOrder
🛒 CustomerOrder ➜ 🔄 becomes ➜ 📦 ProductionOrder

Impact Mapping du langage

Tracez l'impact des changements de vocabulaire :

Changement: "Order" → "CustomerOrder"
Impact:
├── Code
│   ├── 15 classes à renommer
│   ├── 45 méthodes à adapter
│   └── 120 tests à mettre à jour
├── Documentation  
│   ├── API documentation
│   └── User stories
└── Formation
    └── Équipe développement (2h)

Tests comme documentation vivante

[Fact]
public void CustomerOrder_WhenConfirmed_CannotBeModified()
{
    // Given - Un CustomerOrder confirmé
    var order = CustomerOrderBuilder
        .WithOrderLines(Product.Widget, Quantity.Of(5))
        .InStatus(OrderStatus.Confirmed)
        .Build();
    
    // When - On tente d'ajouter une ligne
    var action = () => order.AddOrderLine(Product.Gadget, Quantity.Of(2));
    
    // Then - Une exception métier est levée
    action.Should().Throw<OrderNotModifiableException>()
        .WithMessage("Cannot modify a confirmed CustomerOrder");
}

Métriques et indicateurs

Mesurer l'adoption du langage

Métriques quantitatives :

  • % de classes qui respectent les noms du glossaire
  • Nombre de termes métier dans les noms de méthodes
  • Couverture du glossaire dans les tests

Métriques qualitatives :

  • Fréquence des malentendus en réunion
  • Temps de onboarding des nouveaux développeurs
  • Satisfaction des experts métier

Automatisation des vérifications

// Lint rule personnalisée
const forbiddenTerms = [
    { forbidden: 'Order', preferred: 'CustomerOrder' },
    { forbidden: 'Item', preferred: 'OrderLine' },
    { forbidden: 'Price', preferred: 'Money' }
];

// Vérifie que le code respecte l'Ubiquitous Language
function validateUbiquitousLanguage(codeFile: string): ValidationResult {
    const violations = forbiddenTerms
        .filter(term => codeFile.includes(term.forbidden))
        .map(term => `Use '${term.preferred}' instead of '${term.forbidden}'`);
    
    return {
        isValid: violations.length === 0,
        violations
    };
}

Défis courants et solutions

Résistance au changement

Problème : "On a toujours appelé ça comme ça" Solution : Montrer l'impact business des malentendus actuels

Surcharge cognitive

Problème : Trop de nouveaux termes d'un coup Solution : Introduction progressive, focus sur les concepts centraux

Divergence entre équipes

Problème : Chaque équipe développe son propre vocabulaire Solution : Sessions de synchronisation inter-équipes régulières

Conclusion

L'Ubiquitous Language n'est pas un exercice académique, c'est un outil pratique qui :

  1. Réduit les malentendus entre métier et technique
  2. Améliore la qualité du code en le rendant plus expressif
  3. Facilite la maintenance grâce à un vocabulaire stable
  4. Accélère l'onboarding des nouveaux membres

Points clés à retenir :

  • Commencez par des ateliers collaboratifs
  • Faites évoluer le langage de manière continue
  • Reflétez le vocabulaire dans le code
  • Mesurez et ajustez régulièrement

L'investissement en temps pour construire un Ubiquitous Language solide est toujours rentabilisé par la réduction des malentendus et l'amélioration de la vélocité d'équipe.

📚 À lire aussi

Bounded Contexts : Guide Complet de Mise en Œuvre

Comment identifier, concevoir et implémenter des bounded contexts efficaces dans des domaines complexes. Patterns stratégiques, techniques de context mapping et exemples concrets.

#strategic #bounded-context #architecture