About this chapter
You've learned the styles and patterns. This last chapter is about living with them - the traps you'll hit, the judgment calls, and how to change a system that already exists. You'll start with the most common way DDD goes wrong: the anemic domain model, where entities hold data but no behaviour. Then the counter-weight: when not to use DDD at all, because for simple software these patterns are pure cost. From there it's practical evolution - refactoring a monolith into modules without a rewrite, testing across boundaries (which a clean domain makes cheap), documenting decisions with ADRs and the C4 model so they survive, and the strangler pattern for replacing legacy systems slice by slice. The theme throughout: architecture is never finished, so the real skill is changing it safely.
Lessons from courses
- 1 The anemic domain model The anemic domain model is an anti-pattern: entities that are bags of getters and setters with the logic in services. Why it defeats DDD, with PHP 8.4 before and after.
- 2 When not to use DDD DDD and hexagonal architecture pay off only with real domain complexity. For CRUD, reporting or a tiny team they over-engineer the problem. How to judge, tied to YAGNI.
- 3 Refactoring a monolith into modules Turn a big ball of mud into a modular monolith: find seams by bounded context, enforce boundaries, and extract modules incrementally. You rarely need a rewrite.
- 4 Testing across boundaries The test pyramid for hexagonal architecture: fast unit tests on a framework-free domain, use-case tests with in-memory adapters, a few integration tests on real ones.
- 5 Documenting architecture: ADRs and C4 Record decisions with Architecture Decision Records (context, decision, consequences) and communicate structure with the C4 model. Lightweight, durable docs.
- 6 The strangler pattern The strangler fig pattern replaces a legacy system incrementally by routing slices of functionality to the new one until the old is gone. Safer than a big-bang rewrite.