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)
  • Easy with ORMs
  • Logic scattering
  • Low cohesion
  • 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)