Cinq livres, un système : de la décision d’architecture à une production fiable

Deux interventions sur le même créneau, trois définitions d’un statut et un pipeline au vert juste avant la panne. À partir d’une entreprise de maintenance fictive, nous relions cinq livres essentiels aux décisions dans le code, au DDD, à l’outbox et aux SLO. Avec un parcours animé, un exercice de mise en ordre et un quiz.

L’article complet est disponible ci-dessous. Activez JavaScript pour les quiz et les simulations.

ARCCLOUD / L’ATELIER DE L’ARCHITECTE / 02

Jeudi, tout fonctionnait. Vendredi, deux personnes ont obtenu le même créneau.

L’équipe a ajouté une intégration avec le stock, corrigé le formulaire et livré une version. Le pipeline était au vert. Le lendemain matin, un conseiller a accepté deux interventions pour la même équipe. Une pièce était déjà réservée pour la première ; la seconde avait déjà déclenché l’envoi d’une confirmation au client. Chaque morceau de code faisait quelque chose de raisonnable. C’est l’ensemble du processus qui ne tenait plus.

Dans ces moments-là, l’architecture cesse d’être un dessin fait de rectangles. Elle devient une réponse à des questions précises : qui peut confirmer un créneau, à qui appartient la réservation et qu’avons-nous promis à la personne de l’autre côté de l’écran ?

J’ai choisi cinq livres qui aident à aborder ces questions dans le bon ordre. Nous partirons des exigences, entrerons dans le code, remettrons de l’ordre dans un système existant et vérifierons enfin si nous savons le maintenir après sa mise en production. Chaque livre apporte un regard différent. Tous nous ramènent à la responsabilité des conséquences de nos décisions.

À propos de l’exemple. « Service Nord » est une entreprise fictive qui prend en charge des interventions de réparation. Le récit, les chiffres et les contraintes servent à l’exercice. Les diagrammes, le code et les activités sont des exemples originaux d’ArcCloud, pas des reproductions de contenus tirés des livres. Nous avons vérifié les descriptions des ouvrages auprès des auteurs et des éditeurs le 20 octobre 2026.
01ExigencesQu’est-ce qui doit rester vrai ?
02ModèleOù vit la règle ?
03FrontièresQue faisons-nous évoluer séparément ?
04FluxQue se passe-t-il en cas de panne ?
05ProductionComment savons-nous que cela fonctionne ?

Exigences · Les modèles dans le code · Refactoring · Frontières et événements · Fiabilité · Mettez vos décisions à l’épreuve

01 / FUNDAMENTALS OF SOFTWARE ARCHITECTURE

Une bonne conception commence par un problème que l’on sait nommer.

Mark Richards et Neal Ford présentent les styles d’architecture et les caractéristiques de qualité d’un système. Leur point de départ est simple : toute décision d’architecture a un prix. En gagnant en indépendance de déploiement, nous pouvons rendre les erreurs plus difficiles à suivre. En simplifiant une transaction, nous pouvons lier plusieurs changements à un même déploiement. Ce livre se lit utilement comme un entraînement à justifier ses choix. Présentation de la deuxième édition par l’éditeur.

Chez Service Nord, trois personnes font évoluer une seule application. La plupart des incidents concernent les créneaux et les réservations de pièces. C’est une raison suffisante pour commencer par les règles du processus. Savoir que l’entreprise souhaite une « architecture moderne » ne nous dit pas encore quelle solution l’aidera.

Demande généraleVersion vérifiable dans notre exerciceTest qui révélera le problème
Demande généraleLe système doit être fiable.Version vérifiable dans notre exerciceChaque demande d’intervention acceptée reçoit un identifiant durable et un statut consultable.Test qui révélera le problèmeCoupez la connexion après l’enregistrement et renvoyez une requête identique.
Demande généraleLes créneaux doivent être cohérents.Version vérifiable dans notre exerciceUne même équipe ne peut pas assurer deux visites confirmées qui se chevauchent.Test qui révélera le problèmeDeux requêtes simultanées essaient de réserver le dernier créneau disponible.
Demande généraleLes données doivent être protégées.Version vérifiable dans notre exerciceUn salarié de l’entreprise A ne peut pas consulter une intervention de l’entreprise B, que ce soit par l’API, par un export ou en devinant son identifiant.Test qui révélera le problèmeRépétez les mêmes opérations avec l’identité d’une autre entreprise.
Demande généraleLes changements doivent être simples.Version vérifiable dans notre exerciceUne nouvelle méthode de calcul du devis ne nécessite pas de modifier la planification ni le code d’envoi des messages.Test qui révélera le problèmeAjoutez une variante de devis et observez les modules qu’il faut modifier.

C’est seulement maintenant que la discussion sur le style d’architecture prend son sens. Pour cette entreprise, nous choisissons d’abord un monolithe modulaire: un seul déploiement, avec des frontières de responsabilité explicites. Nous simplifions ainsi la mise en service et pouvons utiliser des transactions locales. Nous acceptons aussi le coût d’une livraison commune et la nécessité de surveiller les dépendances entre les modules.

Ce choix répond aux conditions décrites. Si une équipe distincte commence à faire évoluer la planification, ou si sa charge devient très différente de celle du reste de l’application, nous reviendrons sur cette décision. Un bon document d’architecture précise également le signal qui doit conduire à le relire.

Exemple d’ADR court : pourquoi commencer par un monolithe modulaire ?

Contexte : trois personnes, un seul produit, des règles de réservation qui changent souvent, et aucune équipe d’astreinte distincte pour chaque service.

Décision : les modules Interventions, Planification, Stock et Facturation partagent une application. Chacun expose un contrat et reste responsable de ses écritures.

Conséquences : le déploiement et le diagnostic sont plus simples, mais le processus se met à l’échelle dans son ensemble, avec un risque d’enchevêtrement des dépendances. Les tests d’architecture doivent détecter les accès aux détails internes d’un autre module.

Réexamen de la décision : lorsqu’une équipe distincte apparaît, qu’un besoin de mise à l’échelle indépendante est démontré ou qu’un problème d’isolation des pannes reste sans solution dans l’organisation actuelle.

02 / PATTERNS OF ENTERPRISE APPLICATION ARCHITECTURE

Un modèle n’aide que s’il correspond à la complexité des règles.

Martin Fowler, avec ses coauteurs, décrit les problèmes récurrents des applications de gestion : organisation de la logique, persistance des données ou modifications concurrentes d’une information. L’ancienneté de l’ouvrage n’enlève rien à la valeur de ses questions. En pratique, il est utile de distinguer un simple Transaction Script d’un Domain Model plus riche et de comprendre la frontière d’une Unit of Work. Le livre sur le site de l’auteur.

Supposons que l’administration modifie la description d’un poste de maintenance. Vérifier les droits, contrôler la longueur du texte, enregistrer : un cas simple peut rester un simple script transactionnel. Il n’est pas nécessaire de construire tout un modèle autour de lui.

Confirmer une réparation est plus délicat. Il faut un devis accepté, les pièces et une équipe. Si ces conditions sont vérifiées séparément dans le contrôleur, dans un traitement de nuit et dans une intégration, nous aurons au bout de quelques mois trois définitions différentes d’une « intervention confirmée ». Il devient utile de réunir la règle dans un seul modèle.

public enum WorkOrderState { Draft, Confirmed }

public sealed record ConfirmationEvidence(
    bool QuoteAccepted,
    bool PartsReserved,
    bool TechnicianReserved);

public sealed class WorkOrder
{
    public WorkOrderState State { get; private set; }

    public void Confirm(ConfirmationEvidence evidence)
    {
        if (State == WorkOrderState.Confirmed) return;
        if (!evidence.QuoteAccepted || !evidence.PartsReserved ||
            !evidence.TechnicianReserved)
            throw new InvalidOperationException("Confirmation is incomplete.");

        State = WorkOrderState.Confirmed;
    }
}

Ce fragment illustre une règle, pas un processus prêt pour la production. Dans une application réelle, la preuve de réservation doit provenir d’un contrat de confiance et se rapporter à la bonne intervention ainsi qu’à la bonne version. Il faut aussi gérer l’expiration des réservations, les autorisations et les écritures concurrentes. Trois booléens envoyés par le navigateur ne peuvent pas constituer cette preuve.

Le test unitaire confirme que le modèle refuse des conditions incomplètes. Le test d’intégration lance deux écritures simultanées et vérifie le mécanisme de concurrence en base. Ce sont deux assurances différentes. Le test de la classe seule ne révélera pas une double réservation effectuée par deux processus.

Unit of Work permet de regrouper les changements qui appartiennent à une même opération de persistance. Elle n’étend pas automatiquement la transaction à un stock externe, à un broker et à un serveur de messagerie. Mieux vaut dessiner cette frontière avant que le code ne la franchisse sans que personne ne s’en aperçoive. Présentations succinctes des modèles : Transaction Script, Domain Model et Unit of Work.

03 / DOMAIN-DRIVEN REFACTORING

Clarifiez d’abord les significations. Séparez ensuite le code.

Alessandro Colla et Alberto Acerbis montrent comment appliquer le DDD à un système qui existe déjà : du langage métier et des contextes jusqu’aux changements de structure et de base de données. La démarche compte autant que le résultat : améliorer progressivement les frontières tout en préservant un produit qui fonctionne. Un système modulaire peut être un bon résultat de refactoring ; extraire un microservice demande une justification propre. Le livre chez l’éditeur.

Dans notre entreprise, le mot « prêt » signifie trois choses différentes selon la personne qui l’emploie. Le conseiller pense au prix convenu, le magasinier à la pièce mise de côté et le technicien à la réparation effectuée. Une seule colonne Status n’efface pas cette différence. Elle la dissimule jusqu’au premier cas inhabituel.

Interventions

Objectif de la réparation, accord du client et cycle de vie de l’intervention.

Responsable : gestion du processus.
Planification

Disponibilité de l’équipe, réservation et libération du créneau.

Responsable : organisation du travail.
Stock

Disponibilité des pièces et validité des réservations de matériel.

Responsable : gestion des pièces.
Facturation

Documents, sommes dues et résultat du règlement.

Responsable : finance.

Nous commençons à définir les frontières en parlant avec les personnes qui font le travail. Nous partons d’une réclamation précise : que s’est-il passé, qui a pris la décision et quel fait manquait alors ? C’est de ces échanges que sort un modèle utile. Les noms des dossiers doivent ensuite le refléter.

Comment faire évoluer un ancien système sans tout réécrire ?

  1. Choisissez un scénario qui fait mal. Par exemple, la confirmation d’un créneau. Formulez la règle avec la personne responsable du processus.
  2. Protégez par des tests le comportement dont vous avez besoin. Déterminez quels résultats actuels sont corrects. Figer une ancienne erreur dans un test n’en fait pas une exigence.
  3. Introduisez un seul point d’accès. Le code des interventions demande une réservation à la planification par l’intermédiaire d’un contrat. Il ne modifie pas directement ses tables.
  4. Transférez la responsabilité des écritures. Définissez le moment de la bascule et un responsable unique. Deux mécanismes indépendants qui écrivent les mêmes données rendent les divergences plus difficiles à détecter.
  5. Comparez les résultats et supprimez l’ancien chemin. Vérifiez les données historiques, les cas limites et le plan de retour en arrière. Vous pourrez ensuite supprimer les dépendances devenues inutiles.

À ce stade, la base peut rester commune. Être responsable des données signifie maîtriser leurs modifications, leurs règles et leur contrat ; cela n’impose pas automatiquement un serveur de base de données distinct. Dans un monolithe modulaire, on peut commencer par les schémas, la visibilité des types et les tests de dépendances. Lorsque l’isolation doit être plus forte, on ajoute les autorisations et les frontières d’exécution adaptées.

04 / SOFTWARE ARCHITECTURE: THE HARD PARTS

Quand un module devient un service, le réseau entre dans la discussion.

Neal Ford, Mark Richards, Pramod Sadalage et Zhamak Dehghani analysent les décisions difficiles sur la taille des services, les données, les contrats et les processus distribués. Ce livre est particulièrement utile lorsque plusieurs solutions raisonnables ont des coûts différents et significatifs. Il apprend à comparer les compromis dans le contexte d’un système précis. Présentation du livre par l’éditeur.

Imaginons que la planification dispose désormais de sa propre équipe et s’intègre à plusieurs partenaires. Un service distinct peut donner à cette équipe davantage de liberté de déploiement. En même temps, un simple appel de méthode devient une opération qui peut prendre du retard, s’exécuter deux fois ou se terminer sans réponse. La règle métier reste valable, mais les conditions nécessaires pour la garantir ont changé.

QuestionModule dans un processus communService distinct
QuestionDéploiementModule dans un processus communUne livraison commune demande de la coordination.Service distinctL’indépendance demande des contrats compatibles et un processus de livraison propre.
QuestionDonnéesModule dans un processus communUne transaction locale peut englober les parties qui coopèrent.Service distinctPlusieurs bases impliquent généralement des transactions distinctes et des états intermédiaires explicites.
QuestionPanneModule dans un processus communLes ressources partagées peuvent propager une surcharge.Service distinctL’isolation se construit : délais d’attente, limites de file, maîtrise des tentatives et observabilité.
QuestionDiagnosticModule dans un processus communIl est plus simple de reconstituer une seule pile d’exécution.Service distinctIl faut corréler les requêtes, les événements et les changements d’état.

L’outbox comble une faille précise. Le processus complet demande encore plusieurs décisions.

Si nous enregistrons l’intervention puis envoyons l’événement, le processus peut s’arrêter entre ces deux opérations. L’enregistrement restera en base, mais le message n’arrivera pas. Le modèle transactional outbox enregistre le changement métier et l’intention de publication dans la même transaction locale. Un mécanisme distinct publie ensuite l’événement. Le broker ou le mécanisme de publication peut toujours livrer un doublon : le destinataire doit donc y être préparé. Présentation de l’outbox dans Azure Architecture Center.

CARTE ANIMÉE / VOUS CHOISISSEZ QUAND LA LANCER

Une intervention, plusieurs responsabilités

01Intervention + outboxLa même transaction
02COMMITÉcriture durable
03PublicationEventId stable
04DestinataireChangement + inbox
05ACKAprès l’enregistrement de l’effet

Afficher le parcours étape par étape

Cette courte animation explique l’ordre des opérations. Elle ne se connecte pas à un broker et n’effectue aucun audit d’infrastructure.

Chez le destinataire, l’enregistrement de l’identifiant de l’événement traité et le changement métier doivent former une seule transaction locale, avec une contrainte d’unicité sur le couple destinataire–EventId. Vérifier simplement « l’ai-je déjà vu ? » avant l’écriture ne suffit pas lorsque les messages arrivent en parallèle. Si l’effet attendu est un appel à une API externe, la sécurité des nouvelles tentatives exige une solution distincte, par exemple une clé d’idempotence prise en charge par le fournisseur.

Il nous faut également une politique d’ordonnancement. Un événement en version 8 ne doit pas faire régresser silencieusement une projection qui connaît la version 9. Nous pouvons contrôler les versions et traiter les trous dans la séquence, ou utiliser un mécanisme d’ordonnancement par intervention. Le choix dépend du broker, du mode de traitement et de la portée attendue : un objet ou un ensemble plus large. Imposer un ordre global à tout coûte souvent plus que cela ne rapporte.

Saga et compensation : que pouvons-nous réellement annuler ?

Une fois le stock et la planification séparés, nous n’avons plus une transaction unique pour l’ensemble du processus. Une saga peut coordonner les étapes locales. Si la réservation de l’équipe échoue, nous déclenchons les mesures correctives convenues : libérer la pièce, enregistrer le résultat et informer le service concerné. La compensation peut elle-même échouer ; elle a donc besoin d’un état persistant, de nouvelles tentatives et d’un chemin d’intervention manuelle. Le modèle Saga dans la documentation Microsoft.

Nous ne pouvons pas remonter le temps ni retirer un message déjà lu. Le sens du statut « annulé » doit être défini avec l’entreprise. Si l’état d’une réservation externe est inconnu après un délai d’attente dépassé, nous ne la déclarons pas immédiatement en échec. Nous commençons par déterminer son résultat. L’interface doit afficher honnêtement un état d’attente ou un besoin de vérification, au lieu de promettre que tout est terminé.

05 / SITE RELIABILITY ENGINEERING

L’architecture doit aussi aider la personne qui décrochera le téléphone après une panne.

L’ouvrage dirigé par Betsy Beyer, Chris Jones, Jennifer Petoff et Niall Richard Murphy montre comment relier le développement du produit à la responsabilité de son fonctionnement. Les SLI, les SLO et le budget d’erreur sont un point de départ utile : que mesurons-nous, quel niveau jugeons-nous suffisant et comment réagissons-nous lorsque nous ne le tenons plus ? La version officielle et gratuite du livre.

Pour Service Nord, nous définissons cet objectif à titre d’exemple : sur une fenêtre glissante de 28 jours, au moins 99,5% des demandes d’intervention correctement acceptées reçoivent un résultat correct et durable en moins de 120 secondes. Ce résultat peut être une confirmation ou un refus justifié. Une erreur d’infrastructure renommée « refus » ne devient pas un résultat correct. Nous nous accordons sur la définition avant de commencer à mesurer.

Demandes d’intervention uniques et éligibles20 000
Objectif de l’exemple99,5%
Budget de résultats incorrects ou tardifs100

Il s’agit d’un budget en nombre d’opérations, pas en minutes d’indisponibilité. Les nouvelles tentatives d’une même opération ne doivent pas augmenter le dénominateur. Nous devons aussi définir le traitement des opérations acceptées juste avant la fin de la période d’observation, qui n’ont pas encore disposé de leurs 120 secondes complètes pour se terminer. Sans cette définition, deux équipes peuvent calculer de bonne foi des résultats différents. Les SLI et SLO selon Google SRE.

Un point de terminaison de santé au vert ne suffit pas à confirmer cet objectif. Il faut des événements de début et de fin de processus ainsi que des identifiants cohérents. En complément, nous observons l’âge du plus ancien message de l’outbox, le retard du destinataire, le nombre d’états à vérifier et les compensations en échec. Ces signaux doivent aider à trouver la cause, sans remplacer la mesure de l’expérience utilisateur.

Nous associons au budget une réaction convenue à l’avance. Si le rythme des erreurs laisse prévoir un épuisement rapide du budget, l’équipe limite les livraisons risquées, cherche la cause et améliore la fiabilité. Les correctifs d’urgence et les changements de sécurité font l’objet d’une évaluation du risque distincte. La politique concrète appartient au produit et à son équipe ; vous pouvez partir de l’exemple de politique du livre The Site Reliability Workbook.

Que faut-il garder à côté du code ?

  • Une carte des responsabilités. Qui pilote l’incident et qui connaît chaque partie du processus.
  • Un mode opératoire. Comment retrouver une intervention par son identifiant, reconnaître une nouvelle tentative sans danger et orienter le cas vers une vérification.
  • Un plan de restauration. Une sauvegarde de la base, accompagnée d’une procédure de restauration et de réconciliation de l’état des intégrations, déjà mise à l’épreuve. Le seul statut « sauvegarde effectuée » ne constitue pas un test de restauration.
  • Des conditions de déploiement. Compatibilité des contrats et des migrations, activation contrôlée et critère mesurable pour arrêter la livraison.
  • Les enseignements de l’incident. Ce qui a compliqué le diagnostic, quelle protection a échoué et comment nous vérifierons l’efficacité de la correction.

Revenir à une version précédente de l’application n’annule pas à lui seul les changements de données ni les effets produits dans un système externe. Il faut donc tester le plan de secours sur un scénario qui respecte l’ordre réel des opérations, et pas seulement sur une base de test vide.

ATELIER / DE LA COMPRÉHENSION À LA DÉCISION

Reconstituez le flux. Puis défendez cinq décisions.

Dans le premier exercice, choisissez les étapes dans le bon ordre. Nous supposons une écriture locale de l’intervention avec l’outbox et un destinataire distinct. Les messages peuvent être livrés plusieurs fois. Le résultat de l’exercice reste dans cet onglet du navigateur.

0/5 étapes ordonnées

Publier le message avec un EventId stable

Enregistrer l’intervention et l’outbox dans une même transaction

Accuser réception du message : ACK

Exécuter COMMIT

Enregistrer l’effet et une entrée inbox unique dans la transaction du destinataire

Commencez par préparer un changement durable dans une transaction locale.

Recommencer

Cinq situations du quotidien

0/5

1. Trois personnes, un produit, des réservations problématiques. Par quoi commencez-vous ?

Par l’extraction de toutes les tables vers des microservices.

Par les règles métier, les scénarios de qualité et le coût des solutions.

Choisissez une réponse pour lire l’explication.

2. La même règle de confirmation d’intervention existe dans trois intégrations.

Vous réunissez la règle dans le modèle et vérifiez les autres chemins d’écriture.

Vous renommez les classes en conservant les trois implémentations.

Choisissez une réponse pour lire l’explication.

3. Vous introduisez des modules dans une application ancienne.

Le nouveau module et l’ancien écrivent les mêmes enregistrements de manière indépendante, sans réconciliation.

Vous faites passer un scénario par un contrat et définissez le responsable des données.

Choisissez une réponse pour lire l’explication.

4. Le mécanisme de publication a envoyé le message, mais s’est arrêté avant de le marquer comme envoyé.

Vous prévoyez la possibilité d’un doublon et protégez l’effet chez le destinataire.

Vous supposez que l’outbox élimine tous les doublons.

Choisissez une réponse pour lire l’explication.

5. Pour 20 000 opérations éligibles, quel budget donne un objectif de 99,5% ?

100 minutes d’indisponibilité.

100 résultats incorrects ou tardifs.

Choisissez une réponse pour lire l’explication.

Choisissez une réponse pour chaque situation. Vous pouvez revenir sur votre choix et le corriger.

Reprendre le quiz

Après cette lecture, choisissez une décision à améliorer dans votre système.

Vous n’avez pas besoin de mettre en place tous les modèles à la fois. Décrivez un processus : ce qu’il accepte, où il enregistre la vérité, comment il réagit à une répétition et comment vous reconnaissez sa fin. Repérez les endroits où la réponse repose encore sur une supposition. Cette feuille de travail produit souvent un meilleur plan d’action qu’une liste de nouvelles technologies.

Ordre de lecture : Fundamentals vous aidera à nommer les exigences et les compromis. Chez Fowler, vous trouverez les modèles adaptés à votre logique. Domain-Driven Refactoring sera utile pour remettre de l’ordre dans le code existant, The Hard Parts pour séparer les services et les données, et SRE pour transformer les promesses en mesures et en pratique quotidienne. Revenez au chapitre pertinent lorsqu’une décision concrète se présente.

Vous souhaitez appliquer ces questions à votre application ?

Chez ArcCloud, nous examinons le code, les intégrations, les données et la manière de déployer, puis transformons nos constats en plan de correction priorisé. Dans le périmètre convenu, nous décrivons le problème, son impact, le changement proposé et la manière d’en vérifier l’effet. Après validation du périmètre, nous pouvons aussi réaliser les corrections et présenter les résultats des tests.

Découvrez les périmètres d’audit et présentez votre système →Parlons du problème rencontré dans votre projet →

Livres et sources pour poursuivre le travail

Ce guide original s’appuie sur les sujets abordés dans les ouvrages cités et dans la documentation. Les liens renvoient aux auteurs, aux éditeurs et aux ressources officielles. Les exercices ne nécessitent pas d’acheter les livres.

  1. Fundamentals of Software Architecture, 2nd Edition — Mark Richards, Neal Ford.
  2. Patterns of Enterprise Application Architecture — Martin Fowler, avec les coauteurs mentionnés sur la page du livre.
  3. Domain-Driven Refactoring — Alessandro Colla, Alberto Acerbis.
  4. Software Architecture: The Hard Parts — Neal Ford, Mark Richards, Pramod Sadalage, Zhamak Dehghani.
  5. Site Reliability Engineering — sous la direction de Betsy Beyer, Chris Jones, Jennifer Petoff et Niall Richard Murphy.

Pour aller plus loin : Saga, Transactional Outbox, Service Level Objectives et Error Budget Policy.