Simulateur de Décisions
Affrontez des scénarios réels où vous devez prendre des décisions architecturales et évaluer leurs conséquences à court et à long terme.
Objectif
Dans ce laboratoire, vous allez affronter une série de scénarios où vous devez prendre des décisions architecturales sous des contraintes réelles : temps, budget, équipe et exigences changeantes. Chaque décision entraîne des conséquences qui se révèlent lors des tours suivants.
Comment ça fonctionne
- Lisez le scénario initial avec ses contraintes
- Choisissez parmi les options disponibles (ou proposez la vôtre)
- Lisez les conséquences de votre décision
- Affrontez le scénario suivant qui découle de votre choix précédent
Il n’existe pas de réponses correctes universelles — mais certaines décisions sont mieux fondées que d’autres.
Scénario 1 : Le monolithe qui grandit
Contexte
Votre entreprise possède un monolithe en Node.js qui tourne en production depuis 3 ans. L’équipe est passée de 4 à 12 développeurs. Les déploiements prennent 45 minutes et les conflits de merge sont constants. Le CTO veut « migrer vers les microservices ».
Contraintes
- Budget : pas de moyens pour embaucher davantage
- Timeline : 6 mois pour montrer des résultats
- Le monolithe génère 2 M$/an de revenus — il ne peut pas tomber
Options
Option A : Big bang — tout réécrire en microservices
- Risque : élevé (réécriture complète)
- Temps estimé : 8-12 mois
- Bénéfice potentiel : architecture propre repartie de zéro
Option B : Strangler fig — extraire les services progressivement
- Risque : moyen (changements incrémentaux)
- Temps estimé : 3-6 mois pour le premier service
- Bénéfice potentiel : valeur incrémentale, risque maîtrisé
Option C : Monolithe modulaire — réorganiser sans distribuer
- Risque : faible (refactoring interne)
- Temps estimé : 2-3 mois
- Bénéfice potentiel : meilleure organisation sans complexité distribuée
Conséquences
Si vous avez choisi l'Option A
Au bout de 4 mois, l’équipe a réalisé 30 % du travail. Le monolithe continue de recevoir de nouvelles fonctionnalités parce que le métier ne peut pas attendre. Vous avez désormais deux systèmes à maintenir et l’équipe est divisée. Le CTO commence à demander quand ce sera prêt.
Leçon : Les réécritures complètes se terminent presque jamais à temps. Le métier ne s’arrête pas pendant que vous réécrivez.
Si vous avez choisi l'Option B
Au bout de 3 mois, vous avez extrait le service de notifications. Les déploiements du monolithe sont un peu plus rapides. L’équipe a appris la communication entre services, le service discovery et le monitoring distribué. Vous pouvez maintenant planifier la prochaine extraction avec plus de confiance.
Leçon : Le pattern Strangler Fig permet de migrer progressivement avec un risque maîtrisé. Chaque extraction apporte des enseignements pour la suivante.
Si vous avez choisi l'Option C
Au bout de 2 mois, le monolithe est organisé en modules avec des interfaces claires. Les conflits de merge ont diminué de 60 %. Les déploiements prennent toujours 45 minutes, mais vous pouvez désormais faire des déploiements partiels par module. L’équipe dispose d’une base solide pour extraire des services à l’avenir si nécessaire.
Leçon : Parfois, la meilleure architecture distribuée est celle dont vous n’avez pas besoin. Un monolithe bien organisé peut passer à l’échelle plus que vous ne le croyez.
Scénario 2 : Choisir la base de données
Contexte
Vous concevez un nouveau service d’inventaire. Il doit gérer :
- 500 000 SKUs avec des mises à jour fréquentes
- Des requêtes complexes avec filtres et agrégations
- Un historique des changements pour l’audit
- Des lectures 10x plus fréquentes que les écritures
Options
Option A : PostgreSQL
- Modèle relationnel, ACID complet
- Excellent pour les requêtes complexes
- Scaling vertical + read replicas
Option B : MongoDB
- Modèle documentaire, schéma flexible
- Scaling horizontal natif (sharding)
- Requêtes d’agrégation puissantes
Option C : PostgreSQL + Redis
- PostgreSQL comme source de vérité
- Redis comme cache de lecture
- Complexité opérationnelle accrue
Conséquences
Si vous avez choisi l'Option A
PostgreSQL gère bien les 500K lignes et les requêtes complexes. Au bout de 6 mois, les lectures commencent à saturer la base de données. Vous ajoutez une read replica et le problème est résolu. L’historique des changements, vous l’implémentez avec une table d’audit et des triggers.
Leçon : PostgreSQL est un choix solide pour la plupart des cas. Ne sous-estimez pas jusqu’où peut aller une base de données relationnelle bien configurée.
Si vous avez choisi l'Option B
MongoDB fonctionne bien au début. Au bout de 3 mois, vous découvrez que les requêtes d’agrégation avec plusieurs filtres sont plus lentes que prévu. Le schéma flexible a provoqué des incohérences dans les données parce que différentes parties de l’équipe enregistraient les documents avec des structures légèrement différentes.
Leçon : La flexibilité du schéma est une arme à double tranchant. Sans discipline, elle génère de la dette technique. MongoDB excelle lorsque le modèle de données est réellement hiérarchique.
Si vous avez choisi l'Option C
La combinaison fonctionne très bien pour les lectures. Mais au bout de 2 mois, vous découvrez des bugs d’invalidation de cache : certains utilisateurs voient des données stale après des mises à jour. Vous implémentez un système d’invalidation basé sur les événements et le problème est résolu, mais la complexité opérationnelle a augmenté significativement.
Leçon : Ajouter un cache résout des problèmes de performance mais introduit des problèmes de cohérence. N’ajoutez un cache que lorsque vous en avez réellement besoin, pas « au cas où ».
Scénario 3 : Le service externe qui tombe
Contexte
Votre service de paiement dépend d’un fournisseur externe (Stripe). Ces dernières semaines, Stripe a connu 3 incidents de disponibilité qui ont affecté vos utilisateurs. L’équipe produit veut que « les paiements n’échouent jamais ».
Options
Option A : Ajouter un second fournisseur (PayPal) comme fallback
- Vous dupliquez l’intégration de paiement
- Si Stripe tombe, rediriger automatiquement vers PayPal
- Complexité accrue dans la réconciliation
Option B : Implémenter une file d’attente de reprises
- Les paiements échoués vont dans une file d’attente
- Ils sont réessayés automatiquement avec un backoff exponentiel
- L’utilisateur reçoit une notification lorsque le paiement est traité
Option C : Circuit breaker + dégradation gracieuse
- Détecter rapidement les pannes de Stripe
- Afficher à l’utilisateur un message clair et proposer de réessayer plus tard
- Enregistrer la tentative pour la traiter au retour de Stripe
Conséquences
Si vous avez choisi l'Option A
Ça fonctionne, mais la réconciliation entre deux fournisseurs est complexe. Certains paiements sont traités par Stripe et d’autres par PayPal, ce qui complique les rapports financiers. De plus, PayPal a son propre taux de pannes — il n’est pas immunisé. Au bout de 3 mois, vous disposez d’un système plus résilient mais nettement plus complexe à exploiter.
Leçon : Plusieurs fournisseurs augmentent la disponibilité mais multiplient la complexité. Évaluez si le coût opérationnel justifie l’amélioration de la disponibilité.
Si vous avez choisi l'Option B
Les reprises automatiques résolvent 90 % des pannes transitoires. Mais vous découvrez un problème : certains paiements sont traités deux fois parce que la reprise arrive alors que Stripe avait déjà traité le premier (mais avait répondu par un timeout). Vous implémentez l’idempotence avec des clés uniques et le problème est résolu.
Leçon : Les reprises sans idempotence sont dangereuses. Implémentez toujours l’idempotence avant de mettre en place des reprises automatiques.
Si vous avez choisi l'Option C
Le circuit breaker détecte les pannes en quelques secondes et cesse d’envoyer des requêtes à Stripe. Les utilisateurs voient un message clair : « Le système de paiement est temporairement indisponible. Votre panier est enregistré — vous pouvez finaliser votre achat plus tard. » L’expérience n’est pas parfaite, mais elle est honnête et ne génère pas de frustration.
Leçon : Parfois, la meilleure réponse à une panne est d’être transparent avec l’utilisateur. Tous les problèmes ne nécessitent pas des solutions techniques complexes.
Réflexion finale
Après avoir complété les scénarios, réfléchissez :
- Avez-vous eu tendance à choisir l’option la plus complexe ou la plus simple ?
- Avez-vous pris en compte les contraintes (temps, équipe, budget) ou seulement les exigences techniques ?
- Changeriez-vous une décision en connaissant les conséquences ?
- Quel pattern voyez-vous dans vos décisions ? Êtes-vous conservateur ou audacieux ?
Les meilleures décisions architecturales ne sont pas les plus sophistiquées — ce sont celles qui s’adaptent le mieux au contexte réel du projet.