Apprentissage

📇Carte Context Mapping #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)

Situation 2: Plateforme Core + Multiples Services

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 Context Mapping #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 💭

  1. Qu’est-ce qui est vraiment partagé ? (vs. similaire)
  2. Comment gérons-nous les changements du noyau ?
  3. Qui est responsable de maintenir le Shared Kernel ?
  4. Qu’arrive-t-il si les équipes divergent dans leurs besoins ?
  5. 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 Context Mapping #7 : Published Language

Vue Rapide

🎯 Objectif : Upstream publie un langage standard pour tous les downstream

👥 Relation d’équipe : Upstream/Downstream (nombreux downstream)

📊 Couplage : Bas (via langage public)


Concept

L’équipe upstream publie un langage commun (formats, événements, API) que tous les downstream adopent.

Upstream Service
    ↓
Published Language (JSON Schema, Events, OpenAPI)
    ↓ ↓ ↓ ↓ ↓
Downstream 1, 2, 3, 4, 5... (nombreux)

La philosophie : “Voici notre langage public. Si vous le respectez, ça fonctionne.”

🔗 Dependency Breakers

Identifier et Briser les Dépendances Problématiques

Introduction

Toute architecture complexe accumule des dépendances. Mais pas toutes les dépendances sont bonnes. Certaines deviennent problématiques : elles ralentissent, bloquent, créent du risque, ou violent l’autonomie des équipes.

Ce guide vous aide à :

  1. Identifier les dépendances problématiques
  2. Comprendre pourquoi elles posent problème
  3. Appliquer des patterns pour les “briser” (dependency breakers)

Partie 1: Diagnostiquer les Dépendances Problématiques

Qu’est-ce qu’une Dépendance Problématique?

Une dépendance est problématique si elle a une ou plusieurs de ces caractéristiques:

Atelier Cartographie des Paris Produit

Design de l’atelier “Paris Produit” / “Product Bets”

Pourquoi un atelier ?

Les Product Bets ne sont pas un simple exercice académique. C’est un processus de collaboration intense entre :

  • Les responsables produit
  • Les leaders techniques
  • Les sponsors métier
  • Les stakeholders clés

L’Atelier Paris Produits

Cet atelier de 2 à 3 heures (6-20 participants) est structuré pour :

  1. Introduire le concept des Product Bets et leurs bénéfices
  2. Identifier collectivement les opportunités métier réelles
  3. Construire collaborativement les cartes de chaque pari (hypothèses, risques, ressources, métriques)
  4. Confronter les idées à travers des challenges croisés entre équipes
  5. Prioriser visuellement les paris selon leur valeur estimée vs. leur risque
  6. Capturer l’énergie et engager tous les participants dans l’ownership du résultat

Les 7 cartes en référence

L’atelier utilise 7 zones principales à renseigner pour structurer la réflexion sur chaque Product Bet :

Atelier de Cartographie de Contexte : Mapper les Relations Socio-Techniques

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 Context Mapping #2 : Anticorruption Layer

📇 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 💭

  1. Le modèle upstream pollue-t-il notre domaine ?
  2. Pouvons-nous nous permettre de créer une couche de traduction ?
  3. La traduction est-elle complexe ou simple ?
  4. Comment maintenons-nous la synchronisation entre les deux modèles ?
  5. 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

4. Transformation

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 :

Carte Context Mapping #3 : Conformist

📇 Carte #3 : Conformist

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 💭

  1. Est-ce que le modèle upstream nous convient vraiment ?
  2. Allons-nous devoir le modifier plus tard ?
  3. Quels sont les risques de cette adhérence ?
  4. Comment restons-nous informés des changements ?
  5. 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

Exemples de Conformist Patterns

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

Exemple Concret : Plateforme E-commerce

Contexte

Vous avez une équipe Product Core qui gère l’essai central.

Cartographie de Contexte : Visualiser l'Architecture Socio-Technique

Cartographie de Contexte : Visualiser l'Architecture Socio-Technique

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 :

Cartographie des Paris Produits : De la Théorie à la Pratique

Cartographie des Paris Produits : De la Théorie à la Pratique

Pourquoi les “Product Bets” ?

En octobre 2025, James Shore a prononcé un discours majeur à la conférence Agile Cambridge intitulé “The Accountability Problem”. Ce discours adresse une problématique fondamentale que tout leader d’ingénierie connaît bien : comment démontrer l’accountability de l’équipe de développement logiciel ?

Le problème traditionnel

Généralement, les équipes de développement se voient imposer une forme d’accountability basée sur :

  • Les fonctionnalités à livrer : “Pouvez-vous me promettre la feature X ?”
  • Les dates : “Quand sera-ce terminé ?”
  • La pression budgétaire : “Nous avons X dollars, combien de features cela nous achète-t-il ?”

Or, ce modèle repose sur une fausse prémisse : la croyance que le développement logiciel ressemble à faire un devoir scolaire - une tâche linéaire avec un début, une fin clairement définie, et un chemin prévisible de A à B.