Key Principle
DDD defines failure modes as explicitly as it defines patterns. Each anti-pattern has a specific causal chain explaining how teams arrive there and why it's costly.
Why This Matters
Teams rarely choose anti-patterns deliberately. They arrive through incremental decisions — each reasonable in isolation — that accumulate into systemic problems. Understanding the causal chains enables early detection and prevention rather than expensive remediation.
Good Examples
These are "good examples" of anti-patterns — concrete descriptions of what to recognize and avoid.
Big Ball of Mud: A system with multiple tangled models, no explicit boundaries, and conflicting elements. It appears in three roles throughout the book: as the default failure mode when design is left implicit (Chapter 1-2), as a legacy system to reason about via Subdomain classification (Chapter 3), and as a Context Mapping relationship requiring Anticorruption Layers (Chapter 4). The universal cause: no one chose explicit boundaries, so none exist.
Anemic Domain Model: Objects with getters/setters but no business behavior. The causal chain: technical focus during modeling produces data-centric objects → business logic migrates to Application Services → the "domain model" becomes a persistence mapping layer. "Designing an Anemic Domain Model requires you to take on all the overhead of a domain model without realizing any of its benefits." (Chapter 5). Note: in functional programming, separating immutable data from pure functions is the norm, not an anti-pattern.
Task-Board Shuffle: Teams whose entire design effort consists of moving sticky notes between board columns, leaving all modeling decisions to individual coding heroics. Root cause: management uses Scrum to control timelines rather than enabling knowledge acquisition. (Chapter 1)
Counterpoints
Integration Train Wreck: Context C1 handles a request from C0 by making a synchronous blocking call to S1, creating a cascading failure chain. Fix: messaging eliminates temporal coupling. (Chapter 4)
REST Conformist Trap: Designing REST resources that directly reflect internal Aggregates forces every client into a Conformist relationship. Fix: design resources around client use cases, not internal model structure. (Chapter 4)
Over-Abstraction: Modeling ScrumElement instead of BacklogItem for imagined future flexibility. Breaks the Ubiquitous Language, forces special-case handling, and predicts a future that can't be foreseen. "Don't get taken in by this alluring, highly abstract implementation trap." (Chapter 5)
Immediate Consistency Everywhere: Business stakeholders influenced by database thinking demand everything be immediately consistent. Larger transactional boundaries mean more concurrent modification conflicts, which mean more transaction failures — less consistency in practice. Immediate consistency everywhere is self-defeating. (Chapter 5)
Key Quotes
"Designing an Anemic Domain Model requires you to take on all the overhead of a domain model without realizing any of its benefits." — Vaughn Vernon, Chapter 5
"Don't get taken in by this alluring, highly abstract implementation trap. Model the Ubiquitous Language explicitly according to the mental model of the Domain Experts." — Vaughn Vernon, Chapter 5
Rules of Thumb
- If your system has no explicit boundaries, you have a Big Ball of Mud
- If your domain objects have only getters/setters, you have an Anemic Domain Model
- If design happens only at individual keyboards, you have a Task-Board Shuffle
- If one service failure cascades through your system, you have an Integration Train Wreck
- If your API mirrors your internal model, you're forcing Conformism on clients
Related References
- The Core Framework: Strategic Before Tactical - Why intentional design prevents these failures
- Aggregate Design Rules - Rules that prevent Anemic Domain Models and consistency traps
- Context Mapping Relationships - Patterns that prevent integration failures