Discussion about this post

User's avatar
karl-heinz reichel's avatar

Great article, especially the reframing at the end:

Not “how many files,” but “how much do I need to keep in mind to change a rule?” That’s the real crux of the matter, and I think it can be further clarified in two areas.

**Testing:** The same distinction pays off in testing as well—not simply as “more” or “faster” tests, but as a different kind of test. If the business logic isn’t tied to an ORM, database connection, or HTTP client, it can be validated with simple, cost-effective unit tests—without test containers, without in-memory databases, and without network mocks. When testing a business rule, you don’t have to figure out how to simulate the infrastructure for it simultaneously—it’s the same separation of concerns, just applied to testing instead of coding.

It’s important to note the limitation: This does not replace integration or contract tests at the adapter boundaries. If you rely solely on mocks, you’ll eventually end up testing your own assumptions about the infrastructure rather than the infrastructure itself. The actual effect is better distribution: many inexpensive unit tests for the domain, a few expensive integration tests at the edges—a clean test pyramid that’s hardly achievable without this separation.

**The entity point you mention:** In my experience, this is the most underestimated in the entire article. At first, the domain entity and the ORM entity really do look like pure duplicates—one class, typed twice. But the risk doesn’t become apparent while writing the code; it only emerges later, with the first change.

Without this abstraction, the database structure is effectively passed all the way through to the UI. And with that, the change footprint of every subsequent modification grows: a column change in the database ripples through the ORM, business logic, and API response all the way to the front end—because the same entity is used everywhere, instead of being translated at the domain boundary. This is essentially change coupling between layers that should actually evolve independently of one another.

I’m currently focusing a lot on exactly this kind of structural coupling—how to make it visible in real codebases before it becomes a problem, not after. And one pattern that keeps cropping up: Teams don’t realize just how costly the lack of separation actually was until the third or fourth “trivial” change. At that point, the initial “duplication” suddenly looks very inexpensive by comparison.

No posts

Ready for more?