Anemic Domain Model
Domain objects with no behavior, just data.
“The fundamental horror of this anti-pattern is that it’s so contrary to the basic idea of OO design.” – Martin Fowler
Entities are just bags of getters and setters.
Signs of Use (Symptoms)
- Domain objects look like C structs or DTOs.
- Service classes contain all the business logic (validation, calculation).
- Code is procedural, not object-oriented.
Why it is bad (Consequences)
- Encapsulation violation: Data is exposed to everyone.
- Duplication: Logic that belongs to the entity is repeated in multiple services.
- Inconsistency: Valid state is not enforced by the object itself.
Why it happens (Root Cause)
Influence of frameworks (like EJB or simple ORMs) that encourage separating data from behavior.
When it might be okay (Exceptions)
- DTOs (Data Transfer Objects) explicitly used for crossing boundaries.
- Functional programming styles (where data is immutable and functions are separate).
Explanation
Problem
You have an Order class. But OrderService checks if the order is valid, calculates the total, and adds items.
The Flaw
The Order object is not an object; it’s just data. You lose the benefits of OOP (polymorphism, encapsulation).
Real world analogy
A “Smart Home” where the house is dumb (just walls), and you need an external robot to walk around and turn on every switch manually.
Refactoring Solution
- Move Method: Push logic from the Service into the Domain Entity.
- Rich Domain Model: Ensure objects protect their own invariants.
Pros and Cons (of the Antipattern)
| Pros (Why people do it) | Cons (The price you pay) |
|---|---|
Comparison
- Related Antipatterns: Transaction Script.
- Related Principles: Information Expert, Tell Don’t Ask.
Code example
Typescript
Bad (The Antipattern)
Good (The Fix)
PHP
Bad (The Antipattern)
Good (The Fix)