Layered & Hexagonal Architecture

A track of P38 · Architecture, Services & Distribution.

Keep a growing codebase changeable: refactor a tangled module into ports and adapters so the core depends on interfaces, not concretes, and inject the concrete adapter at the edge - dependency inversion, the lever the whole pillar builds on.

The lever that keeps a growing codebase changeable is where its boundaries sit. This track is layered and hexagonal architecture in practice: depend on interfaces, not concrete classes, so the core stays pure and the details stay swappable.

You refactor a tangled module — one that constructs its own dependency and so can't be tested or repointed — into ports & adapters. The core declares a port (a Protocol) describing what it needs; a concrete adapter implements it; and dependency injection wires the adapter in at the edge. The dependency now points inward, toward the domain, so a test injects a fake and exercises real logic with no I/O, while production injects the real one and nothing in the core changes. That one inversion — depend on an abstraction, inject the concrete — is what the rest of the pillar (services, resilience, the capstone) builds on.

core / domainplain Python, depends on portsporta Protocol: what, not howadapterconcrete impl, injected at the edgedependency inversiondependencies point inward
Keep the core pure; let the details plug in.