5 points par GN⁺ 2025-03-29 | 1 commentaires | Partager sur WhatsApp
  • Les applications Python complexes deviennent, à mesure qu’elles grandissent, difficiles à tester et à faire évoluer avec de simples approches d’implémentation, et ce livre présente comme réponse des patterns d’architecture à travers des exemples de code
  • En prenant comme exemple la vente de meubles en ligne chez MADE.com et une chaîne d’approvisionnement mondiale, il place au centre la modélisation de domaine, c’est-à-dire la transposition des problèmes opérationnels du monde réel en modèles logiciels
  • Les axes principaux sont le TDD, le DDD et l’architecture orientée événements, avec pour objectif des tests unitaires rapides, peu de tests E2E, des modèles séparés de l’infrastructure et une intégration fondée sur les messages
  • Le livre utilise Flask, SQLAlchemy, pytest, Docker et Redis, mais met surtout l’accent sur la création d’une structure où ces choix techniques deviennent des détails d’implémentation
  • Il est accessible à quiconque a déjà travaillé sur des applications Python complexes, sans exiger de connaissance préalable du DDD ni des patterns classiques d’architecture applicative

Partir d’une structure facile à tester

  • Après le précédent livre de Harry, Test-Driven Development with Python, une question restait ouverte : comment structurer une application pour qu’elle soit facile à tester ?
  • L’enjeu central est de construire une architecture où la logique métier est largement couverte par des tests unitaires, tout en réduisant au minimum le nombre de tests d’intégration et de tests E2E
  • Des concepts comme "Hexagonal Architecture", "Ports and Adapters" ou "Functional Core, Imperative Shell" étaient évoqués, mais à l’époque ils n’étaient pas encore suffisamment compris ni réellement mis en pratique
  • Bob est devenu architecte faute de quelqu’un pour tenir ce rôle dans l’équipe, et a appris auprès d’Ian Cooper une nouvelle manière d’écrire du code et de penser les systèmes

Le cas MADE.com : modéliser la supply chain en logiciel

  • Les deux auteurs ont travaillé chez MADE.com, une entreprise européenne d’e-commerce, et y ont appliqué les techniques du livre à la construction de systèmes distribués modélisant de vrais problèmes métier
  • Le domaine d’exemple s’appuie sur le premier système construit par Bob chez MADE et vise aussi à formaliser ce qu’il fallait transmettre aux nouveaux programmeurs rejoignant l’équipe
  • MADE.com exploite une chaîne d’approvisionnement mondiale composée de partenaires de fret et de fabricants
    • Pour réduire les coûts, l’entreprise cherche à optimiser les expéditions afin d’éviter que le stock ne reste trop longtemps immobilisé en entrepôt
    • L’idéal serait qu’un canapé acheté par un client arrive au port le jour même de l’achat, puis soit livré directement chez lui sans stockage intermédiaire
    • Comme l’acheminement des marchandises par porte-conteneurs peut prendre trois mois, le calage temporel est difficile
  • Dans l’exploitation réelle, des variables comme la casse, les dégâts des eaux, les retards dus aux tempêtes, les erreurs de traitement des partenaires logistiques, l’absence de documents ou les changements de commande des clients se produisent en permanence
  • Pour gérer ces problèmes, l’objectif est de représenter les opérations du monde réel dans le logiciel et d’automatiser autant de travail que possible

Les limites qui apparaissent quand un projet Python grossit

  • Python a connu une croissance rapide et a gagné en maturité, mais il commence seulement à prendre en charge à grande échelle des problèmes que les écosystèmes C# et Java traitent depuis longtemps
  • Les startups deviennent de vraies entreprises, et les applications web comme l’automatisation par scripts évoluent vers du logiciel d’entreprise
  • La philosophie de Python affirme “There should be one—and preferably only one—obvious way to do it”, mais quand un projet change d’échelle, la manière la plus obvious n’est pas toujours adaptée pour gérer la complexité et l’évolution des besoins
  • Les techniques et patterns abordés dans le livre ne sont pas nouveaux, mais ils restent relativement récents dans l’univers Python
  • Le livre ne cherche pas à remplacer Domain-Driven Design d’Eric Evans ni Patterns of Enterprise Application Architecture de Martin Fowler ; il s’y réfère souvent et en recommande la lecture
  • Comme les exemples de code de la littérature existante sont souvent écrits en Java ou en C++/#, ils peuvent être plus difficiles d’accès pour les développeurs Python

Trois outils pour maîtriser la complexité

  • Le développement piloté par les tests (TDD) aide à produire du code correct et à refactorer ou ajouter des fonctionnalités sans craindre les régressions
    • Le livre explique comment exécuter les tests le plus vite possible
    • Comment obtenir un maximum de couverture et de feedback avec des tests unitaires rapides et sans dépendances
    • Et comment réduire au minimum les tests E2E, lents et fragiles
  • La conception pilotée par le domaine (DDD) aide à se concentrer sur la création d’un bon modèle du domaine métier
    • Le livre montre comment éviter que le modèle ne soit prisonnier des préoccupations d’infrastructure
    • Et comment éviter qu’il ne devienne difficile à faire évoluer
  • Les microservices faiblement couplés intégrés par messages, parfois appelés reactive microservices, sont présentés comme une réponse à la complexité entre plusieurs applications ou domaines métier
    • En revanche, il n’est pas toujours évident de voir comment cela s’articule avec les outils déjà présents dans l’écosystème Python comme Flask, Django ou Celery
  • Même sans utiliser de microservices, ou sans intérêt particulier pour eux, la plupart des patterns du livre ainsi qu’une bonne partie de l’architecture orientée événements restent applicables à une architecture monolithique

Lecteurs visés et connaissances préalables

  • Le livre s’adresse à des lecteurs ayant déjà côtoyé des applications Python d’une certaine complexité
  • Il est pensé pour celles et ceux qui ont déjà ressenti la douleur liée à la gestion de la complexité
  • Aucune connaissance préalable du DDD ni des patterns classiques d’architecture applicative n’est nécessaire
  • Les explications s’accumulent chapitre après chapitre autour d’une application d’exemple
  • Comme les auteurs utilisent le TDD dans leur travail, ils montrent souvent d’abord les tests, puis l’implémentation
  • Flask, SQLAlchemy, pytest, Docker et Redis sont utilisés, mais les connaître à l’avance aide sans être indispensable
  • L’un des objectifs majeurs est de construire une architecture dans laquelle les choix techniques particuliers deviennent de simples détails d’implémentation

Structure du livre

  • Le livre est divisé en deux parties
  • Partie 1 : une architecture au service de la modélisation de domaine

    • La modélisation de domaine et le DDD sont traités dans les chapitres 1, 2 et 7
    • Le livre part du principe qu’un modèle de domaine dans le code doit refléter des problèmes métier complexes
    • Il explique comment commencer par un modèle sans dépendances externes, testable rapidement via des tests unitaires
    • Il revient ensuite sur le choix des aggregates pertinents et sur les problèmes d’intégrité des données
    • Les patterns Repository, Service Layer et Unit of Work sont abordés dans les chapitres 2, 4 et 5
    • Ces patterns se complètent pour isoler le modèle de dépendances inutiles
    • Ils introduisent une couche d’abstraction autour du stockage persistant ainsi qu’une couche de service qui capture les points d’entrée du système et les principaux cas d’usage
    • Le livre montre une structure qui facilite la création de points d’entrée fins, comme une API Flask ou une CLI
    • La discussion sur l’abstraction et les tests se poursuit dans les chapitres 3 et 5
    • Après l’introduction du pattern Repository, il traite de la manière de choisir une abstraction et du rôle de l’abstraction dans les modes de couplage
    • Après le pattern Service Layer, il aborde la pyramide des tests et la manière d’écrire des tests unitaires au niveau d’abstraction le plus élevé possible
  • Partie 2 : architecture orientée événements

    • L’architecture orientée événements est abordée dans les chapitres 8 à 11
    • Les patterns Domain Events, Message Bus et Handler y sont introduits
    • Les Domain Events servent à exprimer l’idée qu’une interaction dans le système peut déclencher d’autres actions
    • Le Message Bus permet à une action de déclencher un événement et d’appeler le handler approprié
    • Le livre montre comment utiliser les événements comme pattern d’intégration entre services dans une architecture de microservices
    • Il distingue commands et events, l’application devenant fondamentalement un système de traitement de messages
    • Le chapitre 12 présente un exemple de CQRS, avec et sans recours aux événements
    • Le chapitre 13 clarifie les dépendances explicites et implicites et implémente un framework simple d’injection de dépendances
    • L’épilogue explique non pas comment repartir de zéro avec un exemple simple, mais comment appliquer ces principes à un logiciel existant, avec des pistes de lecture complémentaires

Code d’exemple et mise en pratique

  • Le livre est construit autour d’un projet d’exemple unique, enrichi progressivement au fil des chapitres
  • Il accorde de l’importance au fait que le lecteur manipule réellement le code pour acquérir une intuition sur le fonctionnement des patterns
  • Tout le code est disponible sur GitHub, avec une branche distincte pour chaque chapitre
  • Trois façons de suivre le livre sont proposées
    • Créer son propre dépôt, construire l’application en suivant les exemples du livre et consulter le dépôt des auteurs quand nécessaire
    • Essayer d’appliquer chaque pattern, chapitre par chapitre, à l’un de ses petits projets
    • Pratiquer rapidement à l’aide des "Exercise for the Reader" de chaque chapitre et du code GitHub partiellement laissé vide
  • Pour les lecteurs qui veulent surtout appliquer les patterns à leur propre projet, commencer par les exemples simples constitue un terrain d’entraînement sûr
  • Il est au minimum recommandé, à la lecture de chaque chapitre, de récupérer le code avec git checkout dans le dépôt pour l’examiner dans le contexte d’une application réellement fonctionnelle

Licence et conventions typographiques

  • Le code et la version en ligne sont publiés sous licence Creative Commons CC BY-NC-ND
    • Usage non commercial
    • Attribution
    • Copie et partage autorisés
  • L’édition imprimée suit une licence distincte, et en cas de doute sur la réutilisation il est conseillé de contacter O’Reilly
  • Le livre distingue plusieurs conventions typographiques : italique, chasse fixe, chasse fixe en gras et chasse fixe en italique
    • L’italique sert à signaler les nouveaux termes, les URL, les adresses e-mail, les noms de fichiers et les extensions
    • La chasse fixe représente les listings de programme et les éléments de code
    • La chasse fixe en gras désigne les commandes ou textes que l’utilisateur doit saisir tels quels
    • La chasse fixe en italique désigne les textes à remplacer par des valeurs fournies par l’utilisateur ou définies par le contexte

1 commentaires

 
xguru 2025-03-29

Il existe une édition en coréen : Architecture Patterns with Python