Carte Context Mapping #9 : Big Ball Of Mud (BBOM)
📇 Carte #9 : Big Ball Of Mud (BBOM)
Vue Rapide
🎯 Objectif : Reconnaître et documenter une zone chaotique sans structure claire
👥 Relation d’équipe : Sans structure (amorphe)
📊 Couplage : Extrêmement haut (tout touche à tout)
Concept
Une partie du système où les limites sont floues, les responsabilités mélangées, et les dépendances partout.
🌀 BBOM 🌀
├─ Code legacy sans structure
├─ Domaines entrelacés
├─ "Je sais pas comment ça marche"
├─ "Peur de toucher"
└─ Tout change partout
La philosophie : “C’est pas un pattern, c’est un symptôme d’absence de pattern”
Comment Reconnaître une BBOM ?
Signes Techniques
- ❌ Pas de frontières claires : qui possède quel code ?
- ❌ Couplage partout : changer X casse Y, Z
- ❌ Pas de tests : trop complexe à tester
- ❌ Documentation absente : personne ne sait
- ❌ Spaghetti code : impossible de suivre le flux
- ❌ Changements imprévisibles : fix = peut casser n’importe quoi
Signes Organisationnels
- ❌ Plusieurs équipes touchent le même code : conflits constants
- ❌ Peur de déployer : “Et si ça casse ?”
- ❌ Hotfixes urgents : “C’est cassé en prod!”
- ❌ Knowledge silos : “Seul Pierre sait faire”
- ❌ Rotation difficile : nouvelles personnes prennent des mois
Signes Métier
- ❌ Règles métier cachées : découvertes par accident
- ❌ Comportement imprévisible : “C’est pas normal ?”
- ❌ Patches partout : “On fait juste ça ici”
- ❌ Tech debt explosif : accumulation d’années
Quand Vous Avez une BBOM
Ce Que C’est
- C’est une zone de transition : entre legacy et nouveau
- C’est une réalité : beaucoup de systèmes commencent ici
- C’est temporaire : vous avez un plan pour en sortir
Ce Que Ce N’Est Pas
- ✗ Un pattern acceptable long-terme
- ✗ Une “feature” du système
- ✗ “Juste comme c’est”
Questions Clés à se Poser 💭
- Pourquoi c’est une BBOM ? Historiquement, pourquoi ça a dégénéré ?
- Qui la maintient actuellement ? Une équipe ? Plusieurs ?
- Quel est le coût ? Ralentissement, bugs, onboarding ?
- Pouvez-vous l’isoler ? Ou c’est couplé au reste du système ?
- Quel est le plan pour en sortir ? Migration ? Rewrite ?
Contexte Typique : Legacy System
Avant: Monolith 10 ans
legacy_system.exe
├─ User Management (intertwined)
├─ Order Processing (scattered)
├─ Billing (hardcoded)
├─ Reporting (ad-hoc)
└─ Admin Tools (mixed everywhere)
→ Changer "créer commande" touche 20 fichiers
→ Tests ? "On teste en prod"
→ Documentation ? Vous rigolez ?
Stratégies d’Évasion
Option 1: The Strangler Pattern (Recommandé)
Année 1: Extraire microservice #1
├─ Choisir un bounded context clair
├─ Implémenter nouveau service
└─ Router trafic progressivement
Année 2: Extraire microservice #2
├─ Contexte suivant
├─ Router plus de trafic
└─ Legacy devient "legacy"
Année 3+: Sunset legacy
├─ Plus aucun trafic neuf
├─ Archive les données
└─ Éteindre le serveur
Bénéfices:
✓ Risque faible (small increments)
✓ Valeur immédiate (services qui travaillent)
✓ Temps pour apprendre
✓ Peut reverser en cas de problème
Option 2: The Complete Rewrite (Risqué)
"On rewrite tout de zéro"
Risques: ⚠️ TRÈS haut
❌ Calendrier dépassé
❌ Budget dépassé
❌ Oublier des règles métier
❌ Legacy continue à évoluer
Bénéfices: Si ça marche
✓ Clean slate
✓ Modern tech
Conseil: C'est rarement la bonne approche
Option 3: Bubble Context (Hybrid)
Isoler une "bulle" du chaos
└─ Créer Anticorruption Layer
└─ Laisser BBOM en paix
└─ Protéger le nouveau du chaos
Exemple:
BBOM (untouchable)
↓ (ugly interface)
Bubble Context (ACL)
↓ (clean interface)
New Services (protégés)
Exemple Concret : E-commerce Legacy
Avant (BBOM chaotique)
database: 200 tables
├─ ORDERS, ORDER_ITEMS, ORDER_HISTORY
├─ CUSTOMERS, CUSTOMER_ADDRESSES, CUSTOMER_NOTES
├─ PRODUCTS, PRODUCT_VARIANTS, PRODUCT_REVIEWS
├─ INVOICES, INVOICE_ITEMS (mais aussi dans ORDERS!)
├─ USERS, ADMIN_USERS (4 tables d'users)
├─ PAYMENTS, PAYMENT_LOG (inconsistent)
├─ SHIPPING, SHIPMENTS, TRACKING (3 schemas)
├─ CARTS, SESSIONS (qui garder ?)
└─ 50+ tables supplémentaires (qui sait ?)
Application: 1M de lignes de code
├─ No real domain model
├─ Services? Namespaces? Modules? Chacun son style
├─ "Shared" utilities (qui fait 50 choses)
├─ SQL queries partout (pas d'ORM cohérent)
└─ Business logic dans les vues, controllers, models...
Tests: Presque inexistants
├─ Quelques tests UI (fragiles)
├─ Tests unitaires? "Trop couplé"
└─ Tests d'intégration? "Trop lent"
Symptômes
"Créer une facture automatique ?"
→ Chercher dans 3 endroits du code
→ Pas d'API cohérente
→ Risk: va-t-elle dupliquer une commande?
"Changer le format de l'adresse ?"
→ 50 endroits à changer
→ Tests cassent (mais aucun test!)
→ Fix en prod le soir
"Onboard nouveau dev ?"
→ "Lis le code legacy" (pas de doc)
→ 3 mois pour être productif
→ Knowledge silos importants
Après: Strangler Pattern (3 ans)
Year 1: Extract Order Context
New OrderService:
├─ Clean domain model
├─ Event-based integration
├─ Testable (90% coverage)
└─ Router 30% du trafic
Legacy (70%):
├─ Toujours là
├─ Moins de load
└─ Peut focuser sur stabilité
Year 2: Extract Billing Context
BillingService:
├─ Indépendant
├─ Clean model
└─ Router 20% du legacy
OrderService router 50% du trafic
Year 3: Extract Customer Context + Reporting
CustomerService + AnalyticsService:
├─ Clean
├─ Testable
└─ Router 80% du legacy
Legacy (20%):
├─ Read-only
├─ Archive
└─ Prête à éteindre
Year 3+: Sunset
├─ Plus d'appels au legacy
├─ Données migrées
├─ Archive storage seulement
└─ Coûts réduits de 80%
Bulle Context Approach (ACL Around BBOM)
Si tu ne peux pas changer le BBOM
Old BBOM System
↓ (horrible interface)
Bubble Context (ta partie contrôlée)
├─ ACL Layer (traduction)
├─ Domain Model (propre)
└─ APIs (bonnes)
↓ (clean interface)
New Services (heureux)
Code Example
// Le BBOM ne peut pas être changé
// Mais tu peux la wrapper
class LegacyOrderTranslator {
translateFromBBOM(legacyOrder: any): Order {
// Extract ce qui fait sense
return {
id: legacyOrder.order_id,
customer: {
id: legacyOrder.cust_id,
email: this.parseEmail(legacyOrder.contact),
},
// Ignore le chaos
items: this.translateItems(legacyOrder.order_lines),
}
}
}
// New code uses clean model
class OrderService {
getOrder(id: string): Order {
const legacy = this.legacyDb.query(id)
return this.translator.translateFromBBOM(legacy)
}
}
Coûts d’une BBOM
Cost/Benefit Analysis
Yearly Maintenance Cost:
├─ Hotfixes & emergencies: +250%
├─ Knowledge transfer: +200%
├─ Testing & QA: +150%
├─ New features: +300% (longer cycle time)
└─ Total: 2-3x normal cost
Tech Debt Interest:
Year 1: +20% cost
Year 2: +50% cost
Year 3: +100% cost
→ Compound cost grows!
Recovery Roadmap
Phase 1: Assessment (Months 1-2)
- Identify bounded contexts
- Map current state
- Estimate effort
- Choose extraction strategy
Phase 2: Extraction #1 (Months 3-8)
- Build first microservice
- Create ACL/Strangler infrastructure
- Route trafic progressively
- Validate stability
Phase 3: Extraction #2 (Months 9-14)
- Extract next context
- Repeat success
- Monitor legacy reduction
Phase 4+: Systematic Extraction
- Repeat phases 2-3
- Each context smaller, faster
- Monitor cost reduction
- Celebrate wins!
Anti-pattern: Ignoring the BBOM
"C'est pas grave, on va juste laisser comme c'est"
6 months later:
❌ System slower
❌ More bugs
❌ Dev frustrated
❌ Business unhappy
❌ Tech debt explodes
Recommendation: Address it ASAP
Checklist de Mise en Place ✓
- Vous avez accepté que c’est une BBOM (reconnaissance)
- Vous avez compris pourquoi ça s’est passé
- Vous avez un plan de sortie (Strangler, Rewrite, Bubble)
- Leadership supporte l’investissement
- Vous avez identifié les contextes à extraire en priorité
- Vous avez une équipe dédiée au travail de restructuration
Ressources et Lectures
- Domain-Driven Design par Eric Evans - Big Ball Of Mud recognition
- Building Evolutionary Architectures - Strangler Pattern
- Working Effectively with Legacy Code par Michael Feathers
- DDD Crew - Context Mapping
Notes de Facilitation pour l’Atelier
Animation
- Demandez : “Reconnaissez-vous une BBOM ?”
- Testez : “Quel est le coût actuel ?”
- Documentez : “Quel est le plan d’évasion ?”
Pièges Communs
- ⚠️ Nier le problème : “C’est pas si mal…”
- ⚠️ Trop ambition : “On rewrite tout!” (failure)
- ⚠️ Pas de budget : “Pas le temps pour la restructuration”
- ⚠️ Pas de vision : “On verra étape par étape” (converge vers Strangler)
Questions Provocatrices
- “Quel est le coût réel que vous payez chaque jour ?”
- “Si vous continuez 5 ans, qu’arrive-t-il ?”
- “Avez-vous vraiment le courage de refactoriser ?”
- “Qui va mener cette transformation ?”