Anemic Domain Model: Pattern or Anti-Pattern? (Engels)

SOLID principles, Test Driven Development, and functional programming techniques are getting more and more ingrained into the modern programmer’s mind.

That’s obviously a good thing. But it comes with a price: the loss of good old Object Orientation Principles.

One symptom of this trend is the rise of the Anemic Domain Model Anti-Pattern (ADM). An ADM contains data classes without logic and (service) classes containing logic but no data. In fact the code is procedural. In contrast a Rich Domain Model (RDM) is truly Object Oriented: classes contain data and behavior.

AnemicDomainModel Anti-Pattern

The fundamental horror of this anti-pattern is that it’s so contrary to the basic idea of object-oriented design; which is to combine data and process together. The anemic domain model is really just a procedural style design – Martin Fowler

So, ironically, the SOLID principles for Object Orientation will lead to less Object Orientation when applied too rigidly.

According to this blog post from 2014, this doesn’t seem to be a problem:

The Anemic Domain Model is no anti-pattern it’s a SOLID design

The cons of an ADM:

  • Complexer design with more classes
  • Domain logic spread over multiple services
  • Unconstrained mutation of the business model

In my opinion the last point is a very serious flaw of using an ADM.

The pros of an ADM:

  • SOLID principles lead to ADM
  • ADM better supports automatic testing
  • ADM models are more flexible (smaller independent building blocks)

The first argument is actually a non-argument. SOLID principles are not an end in itself. If SOLID principles (meant for OO!) lead to less OO they are flawed!

Not being able to automatically test your code and swap it for something else is a serious problem. But these are straw man arguments, since it is still possible to use an RDM and rely on object composition and dependency injection.

There is no such thing as a single thruth in programming. Programming is a balancing act. I’ll illustrate this with a link to yet another blogpost from 2016 on this subject:

Anemic vs. Rich Domain Objects—Finding the Balance