Layered & hexagonal architecture

P38.architecture.01 · Audience: guest, it-ml, language-pro

Real LLM grading for this pageLLM grading (this page):

As a system grows, the thing that decides whether it stays changeable is where the boundaries are. This pillar is about shaping code into services — and it starts with the oldest lever there is: depend on interfaces, not concretes. This module has you refactor a tangled module into ports & adapters.

Step 1 / 3The tangle: hard-wired dependencies
ⓘ Concept: Constructing your own dependency traps you
When a function constructs an EmailNotifier and calls it, the core logic is welded to that concrete class. You can't test it without sending real mail, and you can't swap the notifier without editing the core. The dependency points the wrong way — from the core out to a concrete detail.

Why it matters — Code that builds its own database or notifier can't be tested without the real thing and can't be pointed elsewhere without editing the core — the root of untestable systems.

The move, in shape: the core stops constructing its dependency and takes it by injection.

from typing import Protocol

class Notifier(Protocol):          # the port: what, not how
    def send(self, message: str) -> None: ...

class OrderService:                # the core depends on the port
    def __init__(self, notifier: Notifier):
        self._notifier = notifier  # injected adapter
Ask the mentor about this module

Ask a question about this content. The mentor explains and grounds its answer in what you are studying; asking is recorded as a learning signal, not a grade.

Ctrl/Cmd + Enter to send

🎓 Practice ladder

2 graded rungs · ~24 min

Refactor a tangled module to ports and adapters, then reason about architecture and boundaries in an interview-style prompt.

Rung 1 — refactor to ports & adapters

Loading exercise…

Rung 2 — architecture & boundaries (interview)

Loading exercise…

With clean boundaries in place, the next module puts a boundary on the outside of the system — an API other code calls.