As Python continues to grow in popularity, projects are becoming larger and more complex. Many Python developers are now taking an interest in high-level software design patterns such as hexagonal/clean architecture, event-driven architecture, and the strategic patterns prescribed by domain-driven design (DDD). But translating those patterns into Python isn’t always straightforward.
With this hands-on guide, Harry Percival and Bob Gregory from MADE.com introduce proven architectural design patterns to help Python developers manage application complexity—and get the most value out of their test suites.
Each pattern is illustrated with concrete examples in beautiful, idiomatic Python, avoiding some of the verbosity of Java and C# syntax. Patterns include:
Dependency inversion and its links to ports and adapters (hexagonal/clean architecture)
Domain-driven design’s distinction between entities, value objects, and aggregates
Repository and Unit of Work patterns for persistent storage
Events, commands, and the message bus
Command-query responsibility segregation (CQRS)
Event-driven architecture and reactive microservices
AI Reading Assistant
Whole-book reading guide from stratified index samples; jump to passages in the text
Tip the Site
Support this siteYour recognition and a small knowledge-service contribution help keep this technical work open source.Scan the WeChat Pay or Alipay code below. Logged-in and guest visitors can both tip.
WeChat Pay
Alipay
Open WeChat or Alipay and scan. No login required.
AI guide
# Architecture Patterns with Python
## 【One-Line Pitch】
A practical guide for Python developers who want to apply proven architectural patterns—domain-driven design, hexagonal architecture, and event-driven systems—to manage growing application complexity and build more testable, maintainable code. If you've outgrown simple Flask/Django apps and want to move beyond "big ball of mud" territory, this book shows you how, with idiomatic Python examples rather than Java-flavored theory.
## 【Book Arc】
- **Opening (~0%–9%)**: Introduces the core problem—Python projects growing too complex for unstructured code—and lays out the book's approach: domain modeling, dependency inversion, and the distinction between entities, value objects, and aggregates. Sets up the running example (a furniture allocation system) and explains why abstractions and layering matter.
- **Early (~9%–25%)**: Builds the foundation: starting with a pure domain model, then introducing the Repository pattern to decouple persistence from business logic. Includes a key interlude on coupling and abstractions—what makes a good abstraction, and how to choose them. Shows how fakes make testing trivial once you depend on abstractions.
- **Early–Middle (~25%–38%)**: Adds the service layer and Unit of Work pattern. Covers test strategy in depth: the test pyramid, when to use mocks vs. fakes, and the classicist vs. London-school TDD debate. The service layer becomes the primary place for business logic tests, with the UoW managing transactions and repository access.
- **Middle (~38%–47%)**: Introduces events and the message bus. Shows how to split orchestration from domain logic using the Single Responsibility Principle, and walks through three options for connecting domain events to handlers—culminating in the UoW collecting events from aggregates and passing them to the bus.
- **Late (~47%–end)**: Extends the event-driven approach to microservices integration (using Redis pub/sub), explores CQRS for separating read and write models, and wraps up with practical guidance on when to apply these patterns. The excerpts cover the chapter structure but not the full content of these final sections.
## 【Key Takeaways】
- **Dependency inversion is the backbone of clean architecture** (Early): By making high-level modules depend on abstractions (like `AbstractRepository`) rather than concrete implementations, you can swap out infrastructure (SQLAlchemy, Postgres, etc.) without touching domain logic. The trade-off: ORMs may not perfectly match your domain model, and "practicality beats purity."
- **The Repository pattern makes testing dramatically easier** (Early): A fake repository wrapping a simple `set()` gives you one-line methods and trivial test setup. This is one of the biggest wins—once you depend on abstractions, fakes become trivial and tests run fast without a database.
- **Choose abstractions to hide messy details** (Early): Good abstractions reduce coupling between components. When you can't change component A for fear of breaking B, you're coupled—and that's the "big ball of mud" problem this book helps you avoid.
- **The service layer is where most tests should live** (Early): Aim for one end-to-end test per feature, the bulk of tests at the service layer (using fakes for I/O), and a small core of domain model tests. Error handling counts as a feature—test happy paths per feature, and reserve one end-to-end test for unhappy paths.
- **Express service-layer functions in terms of primitives, not domain objects** (Early): This keeps the service layer as a clean API boundary, making it testable without hacking state via repositories or databases.
- **The Unit of Work pattern gives you atomic operations** (Middle): By wrapping repository access and commit logic in a context manager, you get simple reasoning about what blocks of code happen together—and you can roll back cleanly if any step fails.
- **Events help separate primary use cases from secondary ones** (Middle): If you can't describe a function without "then" or "and," you're violating the Single Responsibility Principle. Events let the domain model know "we're out of stock" while the responsibility for sending alerts lives elsewhere—switchable without changing business rules.
- **The message bus is dumb infrastructure** (Middle): Think of it as a dict mapping events to handlers. It doesn't understand event meaning—it just routes messages. The UoW can collect events from loaded aggregates and pass them to the bus, keeping handlers clean.
## 【Reading Tips】
- **Skim the opening chapters if you're already familiar with DDD concepts** (~0%–9%): The entity/value object/aggregate distinctions are covered quickly; the real value starts with the Repository pattern discussion.
- **Deep-read the coupling and abstractions chapter** (~19%–25%): This is the conceptual heart of the book. Understanding *why* abstractions matter will make every later pattern click into place.
- **Pay close attention to the test strategy sections** (~25%–34%): The authors are firmly classicist in their TDD approach, and their rules of thumb for test pyramids are immediately actionable.
- **Work through the event/message bus progression carefully** (~44%–47%): The three options for connecting events to handlers build on each other. Don't skip Option 1—the later refinements assume you understand the baseline.
- **The final chapters on microservices and CQRS are lighter in the excerpts** (~47%–end): Skim these for the big ideas (temporal decoupling, read/write model separation) rather than implementation details, since the full code isn't shown in the sample.
## 【Coverage Limits】
This guide covers the book's first half in detail (domain modeling, Repository, service layer, Unit of Work, and events/message bus). The excerpts provide only chapter outlines for the later sections on event-driven microservices and CQRS, so those are summarized at a high level rather than with concrete implementation guidance.
##
Page 9
g CQRS Views f. “Obvious” Alternative 1: Using the Existing Repository g. Your Domain Model Is Not Optimized for Read Operations h. “Obvious” Alternative 2:...
guring out what SQL to write is up to you. Perhaps it’ll be harder than you think; perhaps it’ll be easier. But the nice thing is, the rest of your applicati...
of the implementation for our specific choice of persistent storage also depend on that same abstraction. See Figures 4-3 and 4-4. See also in Appendix C a w...
e mix multiple concerns in one place. Events can help us to keep things tidy by separating primary use cases from secondary ones. We also use events for comm...
see why, let’s consider another case. Sometimes, when stock arrives at the warehouse, we discover that items have been water damaged during transit. We can’t...
re thinking about carving a new system out of a big ball of mud, you’re probably suffering problems with reliability, performance, maintainability, or all th...
he dataclass module to dynamically create our message type. We patch the from_json method onto our dynamic dataclass. We can create reusable parsers for quan...
d dependency injection, Testing Edge to Edge with Fakes and Dependency Injection-Testing Edge to Edge with Fakes and Dependency Injection end-to-end test of...
Support this siteYour recognition and a small knowledge-service contribution help keep this technical work open source.
Scan the WeChat Pay or Alipay code below. Logged-in and guest visitors can both tip.
WeChat PayAlipay
Open WeChat or Alipay and scan. No login required.
Add Tag
Enter tag name (max 50 characters)
Share E-Book
Architecture Patterns with Python (Bob Gregory, Harry Percival) (Z-Library)
Scan QR code with your phone to access
Copy the link or scan the QR code to access this e-book on your phone
Share E-Book via Email
Please enter email address
Donation Statistics
¥.00
Total Donations
0
Donation Count
Architecture Patterns with Python (Bob Gregory, Harry Percival) (Z-Library)
Find Your Favorite Books
Only registered users can comment after logging in. Comments need to be reviewed by administrators before being displayed
Loading comments...
Reply to Comment
Edit Comment