Pourquoi la Cartographie de Contexte ?
La cartographie de contexte est une technique fondamentale du Domain-Driven Design (DDD) qui permet de visualiser les relations entre les contextes délimités (bounded contexts) et les équipes qui les gèrent. Elle répondrait à une problématique majeure en architecture logicielle : comment comprendre et gérer les dépendances dans un système complexe composé de multiples services ou modules ?
Le problème architectural traditionnel
En architecture logicielle, on observe souvent :
- Des couplages implicites : Les équipes ne savent pas exactement comment leurs systèmes interagissent
- Des dépendances cachées : Les impacts des changements ne sont découverts que trop tard
- Un mauvais alignement socio-technique : L’architecture logicielle ne reflète pas la réalité organisationnelle
- Des frictions dans la collaboration : Les équipes travaillent sans langage commun
“Loi de Conway” : L’architecture d’un système reflète la structure organisationnelle qui l’a produite.
La réalité de la complexité distribuée
En réalité, les systèmes complexes modernes sont composés de :
- Plusieurs contextes métier distincts avec leurs propres modèles de domaine
- Plusieurs équipes avec des cultures, compétences et rythmes différents
- Plusieurs patterns de collaboration possibles selon le contexte
- Des relations socio-techniques qui évoluent constamment
La Cartographie de Contexte dans le DDD Starter Modelling Process
La cartographie de contexte n’est pas un exercice isolé. Elle s’inscrit dans une démarche structurée et progressive du DDD Starter Modelling Process - un processus de 8 étapes pour apprendre et appliquer le Domain-Driven Design de manière systématique.
Les 8 Étapes du DDD Starter Modelling Process
Le processus complet comprend :
- Understand (1h) - Aligner avec le modèle métier et les objectifs business
- Discover (2-8h) - Découvrir le domaine visuellement et collaborativement (ex: EventStorming)
- Decompose (1-2h) - Décomposer en sous-domaines loosely-coupled
- Strategize (1h) - Identifier les core domains stratégiques
- Connect (2-3h) - Connecter les sous-domaines en architecture cohérente (ex: Domain Message Flow)
- Organise (2-3h) - ← LA CARTOGRAPHIE DE CONTEXTE EST ICI
- Define (4-6h) - Définir les rôles et responsabilités de chaque bounded context
- Code (∞) - Implémenter le modèle de domaine
Position de la Cartographie de Contexte : L’Étape “Organise”
La cartographie de contexte est une technique clé de l’étape 6 “Organise” du processus. À ce stade :
- ✅ Vous avez découvert et compris le domaine (étapes 1-5)
- ✅ Vous avez identifié les sous-domaines et leurs stratégies
- ✅ Vous avez modélisé les flux de messages entre domaines
- ❓ Maintenant : Comment organiser les équipes et clarifier les relations entre contextes ?
L’objectif de l’étape “Organise”
L’étape “Organise” vise à :
- Organiser des équipes autonomes optimisées pour le flow rapide
- Aligner les équipes avec les limites des contextes (socio-technical architecture)
- Clarifier les patterns et relations d’intégration entre équipes
C’est précisément le rôle de la cartographie de contexte : visualiser ces relations et sélectionner les patterns appropriés pour chaque collaboration.
Flux typique du DDD Starter Modelling Process
1. Understand (Business Model Canvas, User Story Mapping)
2. Discover (EventStorming)
3. Decompose (Sous-domaines, identifiant les limites)
4. Strategize (Core Domain Chart, Wardley Mapping)
5. Connect (Domain Message Flow, flux end-to-end)
↓
6. Organise ← VOUS ÊTES ICI
├─ Context Mapping (cette technique !)
├─ Identifier les équipes
├─ Valider les patterns d'intégration
└─ Aligner structure organisationnelle + technique
↓
7. Define (Bounded Context Canvas)
8. Code (Aggregate Design Canvas, implémentation)
La Cartographie de Contexte : Visualiser la Socio-Technologie
La cartographie de contexte (context mapping) est une technique proposée par Eric Evans dans son ouvrage “Domain-Driven Design” pour rendre ces relations explicites et navigables.
Qu’est-ce qu’une Carte de Contexte ?
Une carte de contexte est une représentation visuelle des bounded contexts et de leurs relations qui capture :
- Les contextes délimités : Des frontières explicites autour de domaines ou services
- Les relations d’équipes : Comment les équipes travaillent ensemble
- Les patterns d’intégration : Les stratégies techniques et organisationnelles de collaboration
Exemple simplifié :
Un système e-commerce composé d’un contexte Catalogue géré par une équipe, un contexte Commandes géré par une autre, et un contexte Facturation distinct.
Les Relations d’Équipes (3 types)
- Mutuellement Dépendants : Les deux contextes/équipes doivent livrer ensemble pour réussir
- Upstream / Downstream : Un contexte influence l’autre de manière asymétrique
- Libres : Aucune relation entre les deux contextes
Les 9 Patterns de Context Mapping
La cartographie de contexte propose 9 patterns pour décrire différentes stratégies de collaboration :
- Open-host Service : Un service expose une interface commune à plusieurs clients
- Conformist : L’équipe downstream adopte le modèle upstream pour simplifier l’intégration
- Anticorruption Layer : L’équipe downstream crée une couche d’isolation pour protéger son modèle
- Shared Kernel : Deux équipes partagent explicitement une partie du domaine
- Partnership : Deux équipes collaborent étroitement sur l’évolution de leurs interfaces
- Customer/Supplier Development : L’équipe downstream a un rôle de “client” dans la planification
- Published Language : Une langue commune documentée permet la traduction entre contextes
- Separate Ways : Les deux contextes n’ont aucune relation intentionnelle
- Big Ball Of Mud : Un anti-pattern : un contexte mal défini où les modèles sont mélangés
Le changement de perspective
Le vrai pouvoir de la cartographie de contexte réside dans le changement de perspective :
Avant (approche naïve) :
- “Voici notre architecture (un grand diagramme sans relations claires)”
- “Les équipes travaillent sur leurs trucs respectifs”
- “Les problèmes d’intégration surgissent en production”
Après (approche cartographiée) :
- “Voici les relations entre nos contextes et comment ils évoluent ensemble”
- “Les équipes comprennent mutuellement leur interdépendance”
- “Les risques d’intégration sont anticipés et gérés”
- “L’architecture reflète et guide la structure organisationnelle”
C’est là qu’intervient l’Atelier de Cartographie de Contexte - un atelier de facilitation conçu pour co-créer la carte de contexte de votre architecture socio-technique avec tous les stakeholders.
Pourquoi un atelier ?
La cartographie de contexte n’est pas un exercice académique solitaire. C’est un processus de découverte collaborative qui nécessite :
- Les représentants des différentes équipes
- Les architectes et tech leads
- Les responsables produit
- Les décideurs organisationnels
L’Atelier de Cartographie de Contexte
Cet atelier de 2 à 3 heures (8-20 participants) est structuré pour :
- Introduire le concept des bounded contexts et des patterns
- Identifier collectivement les contextes délimités actuels
- Mapper les relations entre équipes et contextes
- Sélectionner les patterns appropriés pour chaque relation
- Valider et challenger la carte par tous les participants
- Planifier l’évolution de l’architecture socio-technique
Les 9 Patterns en Référence
La cartographie de contexte utilise 9 patterns principaux (représentés sous la forme de cartes à positionner sur le fond de carte) :
- Open-host Service - Exposer une interface commune
- Conformist - Adopter le modèle upstream
- Anticorruption Layer - Isoler son propre modèle
- Shared Kernel - Partager explicitement une partie du domaine
- Partnership - Collaborer sur l’évolution des interfaces
- Customer/Supplier Development - Relation client/fournisseur planifiée
- Published Language - Langage commun documenté
- Separate Ways - Pas de relation intentionnelle
- Big Ball Of Mud - Anti-pattern à éviter
Les Bénéfices de la Cartographie
Pour les équipes
- ✅ Clarté sur les dépendances et les risques d’intégration
- ✅ Langage commun pour discuter de l’architecture
- ✅ Identification des inefficacités organisationnelles
- ✅ Planification coordonnée des évolutions
Pour l’organisation
- ✅ Alignement entre structure organisationnelle et architecture technique
- ✅ Meilleure prévisibilité des déploiements multi-équipes
- ✅ Identification des goulots d’étranglement
- ✅ Facilitation des reteaming et restructurations
Pour le produit
- ✅ Architectures plus résilientes et évolutives
- ✅ Réduction des défauts liés aux intégrations
- ✅ Meilleure compréhension des impacts de changements
Les 13 Cartes de Context Mapping : Jeu Physique pour Ateliers
Pour faciliter la mise en pratique de la cartographie de contexte, nous avons créé un jeu complet de 13 cartes physiques et numériques, utilisables en atelier présentiel ou hybride.
Les Cartes Disponibles
Patterns d’Intégration (9 cartes)
1. 📇 Open-host Service - Exposer une interface commune
2. 📇 Anticorruption Layer - Isoler son domaine
3. 📇 Conformist - Adopter le modèle upstream
4. 📇 Shared Kernel - Partager du code et un modèle
5. 📇 Partnership - Collaborer étroitement
6. 📇 Separate Ways - Pas de relation intentionnelle
7. 📇 Published Language - Langage commun documenté
8. 📇 Customer/Supplier Development - Co-designer l'interface
9. 📇 Big Ball Of Mud - Anti-pattern et stratégies d'évasion
Relations d’Équipes (3 cartes)
10. 👥 Mutually Dependent Teams - Équipes au même niveau
11. 👥 Upstream/Downstream Teams - Asymétrie intentionnelle
12. 👥 Independent Teams - Complète autonomie
Guide de Sélection (1 carte)
13. 🎯 Matrice de Sélection - Arbre de décision et guide de choix
Utiliser les Cartes en Atelier
Chaque carte contient :
- Vue rapide du pattern / relation
- Quand l’utiliser et quand l’éviter
- Implications pour l’organisation
- Exemple concret
- Questions de facilitation
- Accès à des ressources détaillées (QR code)
Composition du jeu :
- 13 cartes imprimées (A6 ou A5)
- Guide du facilitateur
- Post-its et marqueurs
- Codes couleur pour navigation rapide
Accéder aux Cartes
Format Numérique :
Format Physique :
Aller plus loin : S’inscrire dans une Démarche Globale
La cartographie de contexte n’est qu’une pièce du puzzle du DDD Starter Modelling Process. Pour vraiment tirer parti de cette technique, il faut l’inscrire dans une démarche complète et itérative :
Ce qui DOIT venir avant
- ✅ EventStorming (étape Discover) : Vous devez avoir une compréhension partagée du domaine
- ✅ Décomposition en sous-domaines (étape Decompose) : Vous devez identifier les délimitations naturelles
- ✅ Analyse stratégique (étape Strategize) : Vous devez connaître vos core domains
- ✅ Domain Message Flow (étape Connect) : Vous devez modéliser les interactions end-to-end
Ce qui peut suivre
- ➡️ Bounded Context Canvas (étape Define) : Pour détailler chaque contexte individuellement
- ➡️ Aggregate Design Canvas (étape Code) : Pour concevoir les entités d’agrégat dans le code
- ➡️ Team Topologies : Pour affiner l’organisation des équipes autour des contextes
Ressources Complémentaires
Lectures Incontournables
Les fondamentaux du DDD :
L’approche socio-technique :
- Team Topologies par Matthew Skelton & Manuel Pais
- Dynamic Reteaming par Heidi Helfand
- Sociotechnical Architecture - conférence par Eduardo da Silva
Prochaine Étape : Participez à l’Atelier de Cartographie
Si vous avez complété les étapes 1 à 5 du DDD Starter Modelling Process et que vous cherchez à organiser vos équipes et clarifier vos relations d’intégration, rejoignez-nous pour un atelier de cartographie de contexte.
L’atelier vous permettra de :
- ✅ Cartographier explicitement vos bounded contexts et leurs relations
- ✅ Identifier et sélectionner les patterns de collaboration appropriés
- ✅ Détecter les anti-patterns (Big Ball Of Mud, couplages cachés)
- ✅ Planifier l’évolution vers une architecture plus alignée et autonome
- ✅ Clarifier la structure organisationnelle qui doit suivre
Avant de commencer l’atelier, assurez-vous d’avoir :
- Une bonne compréhension du domaine (EventStorming fait)
- Les sous-domaines identifiés et validés
- Les participants représentant les différentes équipes/contextes
Explorez le design de facilitation et les 9 patterns en détail dans notre guide complet de l’atelier.
Customiser l’Atelier à Votre Contexte
L’atelier standard peut être adapté selon votre situation réelle :
Consultez le guide complet de customisation pour adapter l’atelier à votre structure d’équipes et vos patterns actuels.
Atelier de Cartographie de Contexte
Étape 6 du DDD Starter Modelling Process : “Organise”
(2h à 3h, idéal 8-20 participants)
Contexte : Où sommes-nous dans le DDD Starter Modelling Process ?
Cet atelier intervient après :
- ✅ EventStorming : Vous avez découvert le domaine collaborativement
- ✅ Décomposition en sous-domaines : Vous avez identifié les délimitations naturelles
- ✅ Analyse stratégique : Vous avez identifié vos core domains
- ✅ Domain Message Flow : Vous avez modélisé les flux end-to-end
Maintenant, il s’agit d’organiser les équipes et de clarifier les patterns d’intégration entre contextes. La cartographie de contexte répond à la question :
📇 Carte #1 : Open-host Service
Vue Rapide
🎯 Objectif : Un contexte expose une interface commune à plusieurs clients
👥 Relation d’équipe : Upstream/Downstream (asymétrique)
📊 Couplage : Moyen → Bas (dépend de la stabilité de l’interface)
Concept
L’équipe upstream expose une interface (API, événements, etc.) ouverte et publique que tous les clients downstream peuvent utiliser.
L’interface évolue pour accommoder de nouveaux besoins mais reste cohérente et documentée.
Upstream (Open-host Service)
↓ (API publique stable)
Downstream 1
Downstream 2
Downstream 3 (clients multiples)
Quand l’Utiliser ? ✅
- ✅ Plusieurs clients downstream avec des besoins similaires
- ✅ L’upstream peut réussir indépendamment des clients
- ✅ Vous avez une équipe dédiée pour maintenir l’interface
- ✅ Les besoins des clients sont génériques et prévisibles
- ✅ Vous voulez une approche scalable (ajouter de nouveaux clients facilement)
Exemples
- Stripe API : Interface publique pour les paiements
- Système de catalogue : Expose une API de consultation
- Service d’authentification : Interface standardisée pour login
Quand l’Éviter ? ❌
- ❌ Besoin très spécifique d’un seul client
- ❌ L’interface change constamment (domaine trop exploratoire)
- ❌ Les besoins des clients sont radicalement différents
- ❌ Pas de ressource pour maintenir l’interface
Questions Clés à se Poser 💭
- Y a-t-il plusieurs clients qui consomment ce service ?
- L’interface peut-elle être stable et générique ?
- L’upstream peut-il investir dans la maintenance de l’interface ?
- Les clients acceptent-ils de se conformer à l’interface publique ?
- Comment versionnez-vous l’API pour ne pas casser les clients ?
Implications pour l’Équipe Upstream
Responsabilités
- ✓ Concevoir une interface générique et réutilisable
- ✓ Documenter l’interface publique clairement
- ✓ Maintenir la compatibilité (versioning, backward compatibility)
- ✓ Supporter les clients : comprendre leurs besoins
- ✓ Évoluer l’interface pour accueillir de nouveaux cas
Avantages
- ✓ Scale facilement : ajouter de nouveaux clients sans recoder
- ✓ Faible coupling : les clients n’impactent pas la logique upstream
- ✓ Autonomie des clients : ils peuvent évoluer indépendamment
Risques
- ⚠️ L’interface devient un goulot d’étranglement
- ⚠️ Les besoins des clients créent une interface trop générique ou trop complexe
- ⚠️ Maintenance : gérer plusieurs versions de l’API
- ⚠️ Les clients sont limités à ce que l’interface propose
Implications pour l’Équipe Downstream
Responsabilités
- ✓ Utiliser l’interface telle qu’elle est (pas de négociation)
- ✓ Adapter votre domaine à l’interface upstream
- ✓ Respecter les contrats (versioning, breaking changes)
Avantages
- ✓ Simple d’intégration : pas de traduction complexe
- ✓ Fiabilité : interface bien documentée et stable
- ✓ Pas de dépendance forte : vous pouvez changer sans affecter l’upstream
Risques
- ⚠️ L’interface ne vous convient pas parfaitement
- ⚠️ Adapter votre logique à l’interface plutôt que l’inverse
- ⚠️ Si l’API change, vous devez vous adapter rapidement
Exemple Concret : Système de Paiement
Contexte Upstream : Payment Service
Interface publique (API REST) :
- POST /payments → créer un paiement
- GET /payments/{id} → récupérer le statut
- POST /refunds → effectuer un remboursement
- Events : PaymentCreated, PaymentSucceeded, PaymentFailed
Contextes Downstream
- Order Service : Utilise l’API de paiement
- Subscription Service : Utilise l’API de paiement
- Invoicing Service : Reçoit les événements PaymentSucceeded
Décisions
- ✅ Une seule interface pour tous les cas
- ✅ Versionning : /v1/payments, /v2/payments si breaking change
- ✅ Documentation : Swagger/OpenAPI pour chaque version
Intégration avec Context Mapping
Relations d’Équipe
Payment Team (Upstream - Open-host Service)
↓ (API publique)
Order Team (Downstream - Conformist)
Subscription Team (Downstream - Conformist)
Invoicing Team (Downstream - Conformist)
Patterns Downstream Associés
- Conformist : Les clients adoptent l’interface telle qu’elle
- Anticorruption Layer : Un client crée une couche de traduction (optionnel)
Checklist de Mise en Place ✓
Ressources et Lectures
Notes de Facilitation pour l’Atelier
Animation
- Demandez : “Combien de clients potentiels avez-vous ?”
- Explorez : “L’interface peut-elle rester stable ?”
- Validez : “Quelqu’un d’autre que vous peut-il la comprendre et l’utiliser ?”
Pièges Communs
- ⚠️ Penser que tout est OpenAPI → certains domaines n’y sont pas adaptés
- ⚠️ Négliger la maintenance → les interfaces dégénèrent
- ⚠️ Trop générique → personne ne la comprend
Questions Provocatrices
- “Et si vous aviez 10 clients ? 100 clients ?”
- “Comment réagiriez-vous si un client dit ‘Votre API ne me convient pas’ ?”
📇 Carte #10 : Mutually Dependent Teams (Team Relationship)
Vue Rapide
🎯 Objectif : Deux équipes ont besoin l’une de l’autre - même poids politique
💼 Type de relation : Équipes au même niveau hiérarchique
🔗 Nature : Interdépendance inévitable
Concept
Deux équipes où ni l’une ne peut progresser indépendamment de l’autre.
Team A ←→ Team B
Equal weight
Mutual need
Symmetric relationship
Caractéristiques
Ce qui les Définit
- ✓ Même niveau hiérarchique : pas de subordination
- ✓ Codépendance : l’une ne peut pas avancer sans l’autre
- ✓ Poids politique équivalent : les deux ont du poids
- ✓ Besoin mutuel : pas d’asymétrie
Ce qui les Différencie des Autres
VS. Upstream/Downstream:
→ Upstream/Downstream = asymétrique
→ Mutually Dependent = symétrique
VS. Independent:
→ Independent = zéro dépendance
→ Mutually Dependent = dépendance totale
Exemplesmonde réel
Frontend Team ↔ Backend Team (pour un même produit)
Catalog Service ↔ Inventory Service (interconnectés)
Platform ↔ Billing (même valeur critique)
Client Support ↔ Product Management (input/output)
Implications Organisationnelles
Coordination Nécessaire
- 📅 Sprint planning ensemble
- 🤝 Dailies synchronisées
- 🎯 OKRs alignés
- 📋 Dépendance tracking
Processus de Synchronisation
Decision/Change needed
↓
Both teams discuss
↓
Agree on approach
↓
Implement together
↓
Verify integration
Escalation
Désaccord?
↓
Try to negotiate (48h)
↓
If stuck: escalate to common manager
↓
Manager arbitrates
Patterns Associés aux Mutual Dependency
La plupart des patterns requièrent cette relation:
-
Partnership → Mutually Dependent teams
📇 Carte #11 : Upstream/Downstream Teams (Team Relationship)
Vue Rapide
🎯 Objectif : Une équipe fournit services à l’autre - asymétrique
💼 Type de relation : Hiérarchie implicite (qui dépend de qui?)
🔗 Nature : Dépendance unilatérale
Concept
Une équipe upstream fournit services à une ou plusieurs équipes downstream.
Upstream Team
↓ (provides services)
↓
Downstream Team(s)
Les caractéristiques:
- ✓ Upstream ne dépend PAS du downstream
- ✓ Downstream dépend d’Upstream
- ✓ Asymétrique et clair
Différentes Configurations
1. One Upstream, One Downstream
Payment Service (Upstream)
↓
Order Service (Downstream)
Payment peut évoluer indépendamment.
Order attend Payment.
2. One Upstream, Many Downstream
Product Catalog (Upstream)
↓ ↓ ↓ ↓ ↓
Pricing | Inventory | Search | Recommendation | Analytics
(Downstream services)
Catalog ne connaît pas ses utilisateurs.
Tous dépendent de Catalog.
3. Tiered Upstream/Downstream
Infrastructure (Upstream 1)
↓
Core Platform (Upstream 2)
↓
Business Services (Downstream)
Patterns Possibles dans Upstream/Downstream
Selon la relation, différents patterns:
📇 Carte #12 : Independent Teams (Team Relationship)
Vue Rapide
🎯 Objectif : Deux équipes opèrent indépendamment, zéro dépendance
💼 Type de relation : Aucune (autonome complète)
🔗 Nature : Parallèle, zéro couplage
Concept
Deux équipes qui peuvent progresser complètement indépendamment sans se bloquer.
Team A Team B
(indépendant) (indépendant)
↓ ↓ ↓ ↓ ↓ ↓
(Zéro couplage)
Caractéristiques
Ce qui les Définit
- ✓ Zéro dépendances : l’une peut évoluer sans l’autre
- ✓ Contextes distincts : domaines totalement séparés
- ✓ Données indépendantes : si partage, c’est via batch/events
- ✓ Autonomie complète : aucune coordination requise
Ce qui les Différencie des Autres
VS. Upstream/Downstream:
→ Upstream/Downstream = dépendance
→ Independent = zéro dépendance
VS. Mutually Dependent:
→ Mutually Dependent = interdépendance
→ Independent = complètement libres
Idéal dans Microservices
Architecture
Service A (Independent)
├─ Own code
├─ Own database
├─ Own API
└─ Owns its fate
Service B (Independent)
├─ Own code
├─ Own database
├─ Own API
└─ Owns its fate
Coordination: Minimal (maybe async events)
Implications Organisationnelles
Avantages
- ✓ Complète autonomie : pas d’attendre l’autre
- ✓ Vitesse : chacun va à son rythme
- ✓ Ownership : claire et motivante
- ✓ Scaling : ajoute équipes sans syncro
- ✓ Failure isolation : équipe A crash pas équipe B
Challenges
- ⚠️ Duplication : chacun implémente sa version
- ⚠️ Incohérence : les deux ont des approches différentes
- ⚠️ Outils différents : pas d’unification possible
- ⚠️ Learning silos : pas de partage de connaissance
- ⚠️ Onboarding : chacun a sa culture
Communication: Quand Nécessaire
Pattern 1: Asynchronous Events
Team A does something
↓
Publishes event (OrderPlaced)
↓
Team B picks it up (async)
↓
No blocking, no real-time sync
Pattern 2: Read-Only Access
Team A owns data
Team B reads it (if needed)
↓
No writes between them
↓
Team B can lag behind
Pattern 3: Batch Sync
Team A exports data nightly
↓
Team B imports nightly
↓
Updates 24h later
↓
Acceptable delay
Pattern 4: Complete Separation
Team A: doesn't know B exists
Team B: doesn't know A exists
↓
Zero communication
Exemples du Monde Réel
Auth Team
├─ Handles user login/security
├─ Owns user DB
└─ Exposes API
Reporting Team
├─ Handles analytics/reports
├─ Owns analytics DB
├─ Reads user data (read-only)
└─ Zero coordination needed
Content Team
├─ Manages blog/docs
├─ Owns content DB
└─ Completely separate
E-commerce
Order Service Team
├─ Orders only
├─ Can scale independently
└─ Publishes OrderPlaced events
Inventory Service Team
├─ Inventory only
├─ Listens to OrderPlaced
├─ Decrements stock asynchronously
└─ No blocking dependency
Analytics Team
├─ Reads events (Order, Inventory)
├─ Processes asynchronously
└─ No impact on live systems
Governance
Decision Making
Team A decides its direction → Done
Team B decides its direction → Done
No vetoes, no blocking
Shared Resources?
If need shared infrastructure:
→ Infrastructure team is independent too
→ Or dedicated team owns it
→ But integration still async/event-based
Conflicts
Conflict between teams?
→ Each goes its own way
→ Or escalate to higher-level alignment
Trade-offs
When It’s Perfect
✓ Service A: Payments
✓ Service B: Marketing/Email
✓ Service C: Analytics
→ These can be completely independent
→ Perfect microservices setup
When It’s Not Possible
✗ Frontend & Backend of same product
→ Too coupled, need Partnership or Shared Kernel
✗ Inventory & Orders
→ Need synchronization, not truly independent
✗ Core Platform & Applications
→ Core is needed by apps, Upstream/Downstream better
Cost Analysis
Infrastructure
Benefit: Can scale each independently
Cost: More infrastructure, more databases
Trade-off: Worth it for high-scale systems
Development
Benefit: Teams move fast, no waiting
Cost: Potential duplication, less sharing
Trade-off: Speed > DRY principle (in microservices)
Operational
Benefit: Failure isolated
Cost: More systems to monitor
Trade-off: Worth it for reliability
Indicators
Independence Healthy ✅
✓ Teams deploy independently
✓ No blocking on each other
✓ Different tech stacks OK
✓ Minimal communication meetings
✓ Each owns their metrics
Independence Problematic ❌
❌ Frequent cross-team meetings
❌ Waiting on each other
❌ Duplication becoming costly
❌ Incohesive systems
❌ Can't deploy independently
When to Choose Independence
Right Fit
- Small, focused services
- High-scale systems
- Different business domains
- Different maturity levels
- Different technology choices needed
Wrong Fit
- Tightly coupled features
- Need real-time consistency
- Shared data models
- Young team (need learning)
- Not enough scale to justify overhead
Checklist per Independent Teams ✓
Transitioning to Independence
From Dependent to Independent
Mutually Dependent
↓ (too slow)
Try Partner → Still coupled
↓
Extract: one becomes independent
→ Shared Kernel of critical shared data only
→ Events for everything else
→ Now mostly Independent
From Monolith to Independent
Monolith (all one team)
↓ (slow to scale)
Strangler Pattern:
├─ Extract Service A
├─ Service A becomes Independent
├─ Extract Service B
├─ Service B becomes Independent
├─ ...repeat...
└─ Monolith eventually sunset
Ressources
- Building Microservices par Sam Newman - Team Topology
- Team Topologies par Matthew Skelton - X-as-a-Service
- Release It! par Michael Nygard - Microservice Coordination
- DDD Crew - Context Mapping
Notes de Facilitation pour l’Atelier
Animation
- Demandez : “Êtes-vous vraiment indépendants ?”
- Testez : “Qu’arrive-t-il si Service X casse ?”
- Documentez : “Quelles sont vos vraies dépendances ?”
Pièges Communs
- ⚠️ Dépendances cachées : “Pensaient-ils être indépendants, mais…”
- ⚠️ Trop de duplication : coûteux à maintenir
- ⚠️ Inconsistences : données divergent
- ⚠️ Organisation tue architecture : réorgé casse l’indépendance
Questions Provocatrices
- “Si je change Service A, affecte-t-ça Service B ?”
- “Combien de personnes doivent se synchroniser ?”
- “Est-ce vraiment de l’indépendance ou du chaos ?”
- “Pourriez-vous déployer Service A sans toucher Service B ?”
📇 Carte #13 : Matrice de Sélection des Patterns
Vue Rapide
🎯 Objectif : Choisir le bon pattern selon votre situation
📊 Type : Guide de décision
Arbre de Décision
Q1: Les deux contextes dépendent-ils l'un de l'autre?
├─ NON, zéro dépendance
│ └─ SEPARATE WAYS ✓ (ou Independent Teams)
│
└─ OUI, il y a dépendance
│
├─ Q2: Est-ce une dépendance mutuelle (symétrique)?
│ │
│ ├─ OUI, mutuelle
│ │ │
│ │ ├─ Q3: Vous voulez partager du code?
│ │ │ ├─ OUI → SHARED KERNEL ✓
│ │ │ └─ NON → PARTNERSHIP ✓
│ │ │
│ │ └─ (Relation d'équipe: Mutually Dependent)
│ │
│ └─ NON, asymétrique (Upstream/Downstream)
│ │
│ ├─ Q3: Combien de downstream?
│ │ │
│ │ ├─ Beaucoup (3+)
│ │ │ └─ PUBLISHED LANGUAGE ✓
│ │ │
│ │ └─ Peu (1-2)
│ │ │
│ │ ├─ Q4: Collaborer sur l'interface?
│ │ │ ├─ OUI → CUSTOMER/SUPPLIER DEVELOPMENT ✓
│ │ │ └─ NON
│ │ │ │
│ │ │ ├─ Q5: Le modèle upstream convient?
│ │ │ │ ├─ OUI → CONFORMIST ✓
│ │ │ │ └─ NON → ANTICORRUPTION LAYER ✓
│ │ │
│ │ └─ (Relation d'équipe: Upstream/Downstream)
│
└─ SPÉCIAL: Découvrir un Big Ball Of Mud?
└─ BIG BALL OF MUD = symptôme (stratégie: Strangler)
Puis appliquer les patterns au nouveau code
Matrice Décisionnelle
Par Type de Relation d’Équipe
| Relation |
Patterns Possibles |
Couplage |
Avantages |
Risques |
| Independent |
Separate Ways |
Aucun |
Vitesse, Autonomie |
Duplication |
| Mutually Dependent |
Shared Kernel, Partnership |
Haut/Moyen |
Collaboration, Cohésion |
Synchronisation lente |
| Upstream/Downstream |
Published Language, Customer/Supplier, Conformist, ACL |
Moyen-Bas |
Clarté, Scalabilité |
Blocking sur upstream |
Par Situation
Situation 1: Legacy System + Nouveau Projet
Q: Pouvez-vous modifier le legacy?
├─ NON, intouchable
│ └─ ANTICORRUPTION LAYER
│ (Bubble Context protégeant le nouveau)
│
└─ OUI, progressif
└─ SEPARATE WAYS + Strangler Pattern
(Extraire nouveau, laisser legacy coexister)
Q: Core tient-il le poids?
├─ NON, trop changements
│ └─ SEPARATE WAYS
│ (Chacun sa version)
│
└─ OUI, stable et bon
├─ Peu de consumers
│ └─ CUSTOMER/SUPPLIER DEVELOPMENT
│
└─ Beaucoup de consumers
└─ PUBLISHED LANGUAGE
(Spec stable, chacun sa traduction)
Situation 3: Deux Équipes, Même Produit (Frontend/Backend)
Q: Avez-vous du code réellement partagé?
├─ OUI (domain models, value objects)
│ └─ SHARED KERNEL + PARTNERSHIP
│
└─ NON, juste interfaces
└─ PARTNERSHIP
(API négociée, chacun son code)
Situation 4: Données Critiques Partagées
Q: Temps-réel synchronisation requise?
├─ OUI, toujours sync
│ ├─ Même équipe/code
│ │ └─ SHARED KERNEL (literal)
│ │
│ └─ Équipes différentes
│ └─ PARTNERSHIP + synchrone
│ (Risque: tightly coupled)
│
└─ NON, batch/async OK
└─ SEPARATE WAYS + Events
(Broadcast events, each reacts asynchronously)
Par Critères Techniques
Critère: Modèle Upstream Compatible?
Compatible?
├─ OUI, parfait fit
│ └─ CONFORMIST
│
└─ NON, beaucoup diffère
└─ ANTICORRUPTION LAYER
Critère: Interface Complexité
Traduction simple?
├─ OUI (champs directs)
│ └─ CONFORMIST ou ACL simple
│
└─ NON (calculs, agrégation)
└─ ACL complexe
ou chercher alternative (Published Language?)
Critère: Scalabilité
Combien de consumers?
├─ 1-2
│ └─ Upstream/Downstream simple OK
│
├─ 3-5
│ └─ Published Language commence
│
└─ 5+ ou communauté
└─ Published Language obligatoire
(ou découpler vers Independent)
Par Coût d’Intégration
Coût TRÈS haut?
├─ OUI (complexe, risqué)
│ └─ Réévaluer dépendance
│ └─ Considérer SEPARATE WAYS
│ └─ Ou créer ACL (isolation)
│
└─ NON, acceptable
└─ Choisir selon la relation d'équipe
Anti-patterns à Éviter
❌ Anti-pattern 1: Partnership Sans Communication
"On va faire de la partnership!"
→ Pas de réunions régulières
→ Changements unilatéraux
→ Dépendances cassées
Correction: Ajouter governance (réunions, process)
Ou revenir à Upstream/Downstream plus clair
❌ Anti-pattern 2: Shared Kernel Sans Propriétaire
"On partage le code!"
→ Personne ne le maintient
→ Divergence progessive
→ Chacun ajoute ses trucs
Correction: Nommer responsables du kernel
Ou réduire à vraiment partagé
❌ Anti-pattern 3: Trop d’Upstream/Downstream
"Platform est upstream de 50 services"
→ Platform bottleneck
→ Trop lent, trop tendu
Correction: Migrer vers Published Language
Ou découpler (services Independent)
❌ Anti-pattern 4: Oublier la Team Relationship
"On applique Shared Kernel"
→ Mais équipes ne communiquent jamais
→ Chaos prévisible
Correction: Pattern compatible avec relation d'équipe!
Feuille de Décision Rapide
Remplissez:
Question 1: Dépendance mutuelle ou asymétrique?
📇 Carte #2 : Anticorruption Layer (ACL)
Vue Rapide
🎯 Objectif : L’équipe downstream crée une couche d’isolation pour protéger son modèle
👥 Relation d’équipe : Upstream/Downstream (asymétrique)
📊 Couplage : Bas (isolation complète)
Concept
L’équipe downstream crée une couche de traduction (ACL) qui :
- Traduit le modèle upstream en modèle downstream
- Isole le domaine downstream des changements upstream
- Protège l’indépendance du downstream
Upstream (modèle compliqué/différent)
↓
Anticorruption Layer (translation)
↓
Downstream (modèle propre et indépendant)
Quand l’Utiliser ? ✅
- ✅ Les modèles upstream et downstream sont radicalement différents
- ✅ Vous voulez protéger votre domaine des pollutions upstream
- ✅ L’upstream change fréquemment ou est mal conçu
- ✅ Vous avez besoin d’indépendance maximale
- ✅ L’interface upstream est imposée et immuable
Exemples
- Legacy System Integration : Intégrer un vieux système avec ACL
- Third-party API : Adapter une API externe à votre domaine
- Big Ball Of Mud : Isoler votre domaine du chaos upstream
Quand l’Éviter ? ❌
- ❌ L’interface upstream est simple et stable
- ❌ Vous pouvez vous permettre d’adopter le modèle upstream (Conformist)
- ❌ La complexité de traduction est excessive
- ❌ Vous avez besoin de synchronisation temps-réel très serrée
Questions Clés à se Poser 💭
- Le modèle upstream pollue-t-il notre domaine ?
- Pouvons-nous nous permettre de créer une couche de traduction ?
- La traduction est-elle complexe ou simple ?
- Comment maintenons-nous la synchronisation entre les deux modèles ?
- Où plaçons-nous l’ACL : au niveau de l’équipe ou du service ?
Implications pour l’Équipe Downstream
Responsabilités
- ✓ Concevoir l’ACL : mapper upstream → downstream
- ✓ Maintenir l’ACL : gérer les évolutions upstream
- ✓ Documenter les mappings : pourquoi cette traduction ?
- ✓ Tester l’ACL : validation des conversions
Avantages
- ✓ Indépendance totale : votre domaine est protégé
- ✓ Flexibilité : vous pouvez changer sans affecter l’upstream
- ✓ Clarté : votre code est clair, la traduction est centralisée
- ✓ Évolutivité : remplacer upstream ne casse pas votre logique
Risques
- ⚠️ Complexité : maintenir une couche de traduction
- ⚠️ Performance : la traduction peut avoir un coût
- ⚠️ Synchronisation : gérer les changements upstream
- ⚠️ Duplication : code de mapping qui peut devenir lourd
Patterns de Traduction Courants
1. Mapping Simple
Upstream: Order { items: [], total: 0 }
↓
ACL: convertOrderToOurModel()
↓
Downstream: PurchaseOrder { lineItems: [], grossAmount: 0 }
2. Enrichissement
Upstream: minimal data
↓
ACL: enrichir avec contexte (user, country, etc.)
↓
Downstream: complete domain object
3. Agrégation
Upstream 1: User data
Upstream 2: Address data
↓
ACL: combiner les sources
↓
Downstream: Customer aggregate
Upstream: Legacy format
↓
ACL: parser, validator, transformer
↓
Downstream: Modern format
Exemple Concret : Integration d’un Legacy System
Contexte Downstream : Nouvelle Commande Service
Votre domaine clair et moderne :
Vue Rapide
🎯 Objectif : L’équipe downstream adopte le modèle upstream sans traduction
👥 Relation d’équipe : Upstream/Downstream (asymétrique)
📊 Couplage : Haut (adhérence au modèle upstream)
Concept
L’équipe downstream accepte simplement le modèle et les conventions de l’équipe upstream.
Upstream (modèle de référence)
↓ (pas de traduction)
Downstream (adopte le même modèle)
La philosophie : “Ce que vous donnez, nous l’utilisons tel quel”
Quand l’Utiliser ? ✅
- ✅ Le modèle upstream est suffisamment bon pour votre besoin
- ✅ Créer une ACL serait trop complexe ou non rentable
- ✅ L’upstream est stable et bien conçu
- ✅ Vous avez une dépendance forte et c’est acceptable
- ✅ L’équipe upstream a du poids politique ou est essentielle
Exemples
- API publique stable : Adopter directement une API bien conçue
- Plateforme core : Tous les services acceptent le modèle core
- Standard industrie : Utiliser un standard reconnu (ISO, RFC, etc.)
Quand l’Éviter ? ❌
- ❌ Le modèle upstream est incompatible avec votre domaine
- ❌ L’upstream change fréquemment sans coordination
- ❌ Vous avez besoin de dépendances croisées (Partner pattern est meilleur)
- ❌ C’est une dépendance temporaire (better: Anticorruption Layer)
- ❌ Le modèle upstream est mal conçu (Big Ball Of Mud)
Questions Clés à se Poser 💭
- Est-ce que le modèle upstream nous convient vraiment ?
- Allons-nous devoir le modifier plus tard ?
- Quels sont les risques de cette adhérence ?
- Comment restons-nous informés des changements ?
- Qui décide des évolutions du modèle shared ?
Implications pour l’Équipe Downstream
Responsabilités
- ✓ Accepter le modèle tel qu’il est
- ✓ Communiquer rapidement si le modèle pose problème
- ✓ Collaborer avec upstream pour améliorations
- ✓ Supporter les changements d’upstream
Avantages
- ✓ Simple : pas de couche de traduction
- ✓ Rapide à intégrer : implémentation directe
- ✓ Couplage intentionnel : c’est du domaine partagé
- ✓ Moins de bugs : une seule source de vérité
Risques
- ⚠️ Pollina votre modèle : compromis sur votre pureté
- ⚠️ Couplage fort : difficile à défaire
- ⚠️ Bloqué par upstream : changements lents
- ⚠️ Conflit de visions : deux domaines, une structure
Implications pour l’Équipe Upstream
Responsabilités
- ✓ Maintenir une API stable : les downstream dépendent de vous
- ✓ Communicer les changements : informer rapidement
- ✓ Respecter la compatibilité : ou avoir un processus de migration
- ✓ Écouter les besoins downstream
Avantages
- ✓ Influence : votre modèle devient référence
- ✓ Couplage maîtrisé : par design
Risques
- ⚠️ Responsabilité : you break it, you own all the consequences
- ⚠️ Évolution lente : devoir négocier avec tous les conformists
1. Shared Business Model
Upstream Team (Orders Domain)
├── Order { id, customerId, items, status }
├── OrderItem { productId, quantity, price }
└── Status enum
Downstream Team (Invoicing)
└── Adopte exactement le même modèle
├── Invoice utilise Order directement
├── InvoiceItem utilise OrderItem
└── Respecte Status enum
2. API Publique Standard
Upstream: REST API (JSON well-known)
{
"id": "...",
"name": "...",
"type": "...",
"metadata": { ... }
}
Downstream Services:
└── Tous utilisent exactement cette structure
Pas de traduction
3. Industrie Standard (XML/JSON Schema)
Standard: UBL Invoice
Upstream (supplier): génère UBL
Downstream (customer): consomme UBL
→ Pas de traduction
Contexte
Vous avez une équipe Product Core qui gère l’essai central.
📇 Carte #4 : Shared Kernel
Vue Rapide
🎯 Objectif : Deux équipes partagent du code et un modèle commun
👥 Relation d’équipe : Mutuellement Dépendant
📊 Couplage : Très haut (code partagé)
Concept
Deux contextes partagent du code source et un modèle de domaine commun.
Shared Kernel (Code + Model)
↙ ↘
Team A Team B
Le noyau partagé n’appartient à aucun contexte, il est gardé par les deux.
Quand l’Utiliser ? ✅
- ✅ Deux équipes très dépendantes l’une de l’autre
- ✅ Créer une interface prendrait plus de temps qu’un code partagé
- ✅ Les équipes veulent vraiment collaborer
- ✅ Le code partagé est stable et bien défini
- ✅ C’est une zone de frontière claire (pas du fouilli)
Exemples
- Domain Entities partagées : Customer, Product (tous les services en ont besoin)
- Value Objects : Money, EmailAddress (immuables, réutilisables)
- Shared Policies : Règles métier communes
- Shared Algorithms : Calculs complexes partagés
Quand l’Éviter ? ❌
- ❌ Les équipes ne se font pas confiance
- ❌ Le code partagé change fréquemment
- ❌ Vous pouvez le dupliquer (plus simple)
- ❌ Le code partagé n’est pas vraiment partagé (distinct par contexte)
- ❌ Les équipes sont géographiquement éloignées (communication difficile)
Questions Clés à se Poser 💭
- Qu’est-ce qui est vraiment partagé ? (vs. similaire)
- Comment gérons-nous les changements du noyau ?
- Qui est responsable de maintenir le Shared Kernel ?
- Qu’arrive-t-il si les équipes divergent dans leurs besoins ?
- Comment versionnons-nous ce code partagé ?
Implications pour les Deux Équipes
Responsabilités Communes
- ✓ Maintenir ensemble le Shared Kernel
- ✓ Tester à fond : les changements affectent tous les contextes
- ✓ Documenter clairement : quoi et pourquoi c’est partagé
- ✓ Communiquer avant changement
Avantages
- ✓ Efficacité : pas de duplication ou traduction
- ✓ Cohérence : une seule source de vérité
- ✓ Collaboration : force les équipes à travailler ensemble
- ✓ Évolution facile : tout le monde évolue en même temps
Risques
- ⚠️ Couplage très fort : changement = impacte les 2 contextes
- ⚠️ Synchronisation lente : besoin de coordination
- ⚠️ Conflits : si les besoins divergent
- ⚠️ Cycles de dépendance : chaque équipe attend l’autre
Structure du Shared Kernel
Option 1 : Bibliothèque Partagée
shared-kernel/ (repository/package dédié)
├── domain-entities/
│ ├── Customer.ts
│ └── Product.ts
├── value-objects/
│ ├── Money.ts
│ └── EmailAddress.ts
└── policies/
└── PricingPolicy.ts
Team A → imports shared-kernel
Team B → imports shared-kernel
Option 2 : Code Partagé dans Sous-Dossier
monorepo/
├── services/team-a/
│ ├── src/
│ └── shared/ (lien vers shared-kernel)
├── services/team-b/
│ ├── src/
│ └── shared/ (lien vers shared-kernel)
└── shared-kernel/
├── entities/
├── value-objects/
└── policies/
Exemple Concret : E-commerce Shared Entities
Contexte
Deux équipes : Catalog et Inventory
📇 Carte #5 : Partnership
Vue Rapide
🎯 Objectif : Deux équipes avec besoin mutuel s’engagent à se coordonner
👥 Relation d’équipe : Mutuellement Dépendant
📊 Couplage : Élevé (interfaces négociées)
Concept
Deux contextes aussi importants l’un que l’autre s’engagent à :
- Collaborer sur les interfaces
- Se consulter avant changements majeurs
- Synchroniser leurs efforts
Team A (contexte équivalent)
↔ Partnership ↔
Team B (contexte équivalent)
La philosophie : “Nous avons besoin l’un de l’autre, donc on se coordonne”