Persistence model and domain anemia

Domain anemia is a term thrown around like it’s a horrible disease.  However, a while back, Greg Young talked about an intentional decision to create an anemic domain model.  In some contexts, an anemic domain model is an anti-pattern.  Instead, I see a rather different issue going on here.  For the vast majority of systems built that I’ve encountered, a true domain model is overkill.  But what is the domain model pattern?  It could be all the way to a CQRS system, or it could be a system where your entities are more than containers of data, but containers of behavior.

The real problem is the assumption from folks doing an anemic domain model that they’re doing DDD or doing a domain model pattern.  But if your entities only expose data, it’s not a domain model.  This isn’t necessarily a bad thing though.  It’s more important that this decision is intentional.

Anemic domain model has a negative connotation, so I’d like to get rid of that term used to describe the intentional decision to create an anemic model.  Instead, I like the term Persistence Model or Persistent Object Model to describe an intentionally anemic domain model.

The Persistence Model Pattern

In the Persistence Model pattern, entities are designed with names matching the ubiquitous language.  They represent real concepts in the model, and a domain expert can communicate about these entities with the developers.  However, in a Persistence Model, entities can be talked about synonymously with the backing database tables that hold the persisted information.  Relationships drawn between entities represent foreign keys, and “Entity” and “Table” are interchangeable in every day communication.

Designing of a Persistence Model can be accomplished through model-driven design or database modeling, as the entities have a one-to-one relationship to the backing database.  The structure of the entities will still benefit from POCO design guidelines, as the separation of concerns between the actual mapping in and out of the database is easily solved by ORMs.  The impedance mismatch from objects in an OO language and set-based data in a database is still large enough that an ORM provides immense value.  Additionally, ORMs that provide model-driven design capabilities (such as the EF entity designer) are optimized for the Persistence Model pattern.

The Persistence Model pattern can be recognized because the entities themselves are largely not responsible for their own consistency.  For example, you will likely see public mutators (setters) and collections exposed directly.  Entities are used for querying and visualizing data, and for capturing user input and persistence.  Entities do not react to events or “when” things occur, but rather they are largely brainless, strongly-typed data containers.

Because many systems do not have much complexity around their domains, it is far less often that a system needs to do something as a result of an entity changing.  In forms-over-data and records management applications, the system is primarily concerned with getting data and in and out.

Context is king

So when is the Persistence Model pattern appropriate?  If you’ve already ruled out using straight-up datasets or reading straight from a persistence layer, this pattern is worth looking at.  If you can’t or don’t need a full-on domain model, a persistence model will still help with the impedance mismatch with the persistence mechanism.

Times when you can’t do a full domain model can include situations where you don’t have access to a domain expert, your team isn’t experienced with OO, or time constraints limit the conversations and analysis needed to build a decent domain model.  If the domain isn’t complex, or is largely data-in, data-out, then those are contexts where a full domain model likely isn’t needed as well.

Domain models are usually persistent, but I’d like to separate the definition of an attempted domain model that ends up being anemic, versus creating a persistent object model that is intentionally anemic because there is no need for anything more.  The anemic domain model anti-pattern is well-known and described, but it shouldn’t be applied to all contexts of a behavior-less persistent object model.

Related Articles:

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

About Jimmy Bogard

I'm a technical architect with Headspring in Austin, TX. I focus on DDD, distributed systems, and any other acronym-centric design/architecture/methodology. I created AutoMapper and am a co-author of the ASP.NET MVC in Action books.
This entry was posted in Domain-Driven Design. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Rob M

    Great post – sums up succinctly thoughts I’ve been having recently

  • http://joshilewis.wordpress.com Joshua Lewis

    I’m not sure I’m understanding this. From what I understand, in your ‘Persistence Model’ pattern, the objects don’t seem to have much behaviour. This pattern also doesn’t ‘OO’ to me – you explicitly state the these objects don’t have behaviour and contain only data.

    How are the objects in this pattern different to data transfer objects emitted from the persistence layer (which may or may not be transformed into ‘real’ objects at another layer in a layered architecture)?

    I don’t see how this pattern is a domain model at all. It seems like you are just wrapping the data in classes?

  • http://www.lostechies.com/members/bogardj/default.aspx bogardj

    @joshua

    Exactly. A persistence model is not a domain model. They are dumb data objects, and their only behavior is on the query side.

  • http://ThisOldCode.net Aaron

    So the Persistence model is more Domain Value Model Rather then Domain Object Model?

  • AJ

    Great post, thanks. Very relevant to stuff I’m working on right now.

    In a “pure” domain model, what actually goes on your entities other than getters/setters? Does “behavior” simply consist of designing the relationships from your schema into the entities? Or, in .NET (for example) does adding overrides for Equals, ToString, etc., even if there is a one-to-one relationship between DTO classes and tables in the schema, qualify a library to be “domain modeled” rather than “persistence modeled?”

  • http://www.lostechies.com/members/bogardj/default.aspx bogardj

    @AJ

    I have some more posts in the pipeline around these concepts, but Udi’s blog and Laribee’s posts on “super models” are a great start.

    @Aaron

    I would say a persistence model isn’t a domain model at all. It resembles an anemic domain model, but I’d say it’s more along the lines of a “object model that matches the DB schema, plus names come from the ubiquitous language”.

  • http://opletayev.blogspot.com/ Mikhail Opletayev

    Good post!

    > In forms-over-data and records management applications, the
    > system is primarily concerned with getting data and in and out.

    I think this is the key for many applications: splitting them into semi-independent components that can view the data that way.

    While it’s true that this approach doesn’t work well for complex domain models, I happen to think that the focus need to be on splitting those models into isolated components that are easier to define, rather than condemning a model as an anti-pattern.

    http://opletayev.blogspot.com/2009/12/anemic-domain-model.html

  • http://jack.ukleja.com Jack Ukleja

    “Designing of a Persistence Model can be accomplished through model-driven design or database modeling, as the entities have a one-to-one relationship to the backing database”

    One of the big things about EF (via the EDM) is it allows your entity model to be different to the data[base] model which lies underneath, so your comment above does not hold.

  • http://www.lostechies.com/members/bogardj/default.aspx bogardj

    @Jack

    Yes, I was referring to the ability to create entities and what not via a designer. Linq-to-SQL has the same advantage. I know EF now supports POCO and what not, but it still has a great experience for development when DB schema == persistence model.

  • Arnis L.

    Recently talked with my co-worker – tried to explain single responsibility principle and why sometimes there’s need for DTO`s.

    He highly disliked idea about ‘code duplication’ and mentioning ease of object2object mapping nowadays didn’t help either. :)

    Then i drew a small circle in mspaint and filled it red. Told him to think about it as class that contains hyper complex logic inside (visualization of nested ifs/fors 10 levels deep does do the trick). And drew 2 larger circles that i filled green (where color just like before – indicates complexity). Then i told – adding another abstraction layer basically is the same thing what i just drew – we inflate something complex (and, if necessary – split) to make it simple, more human mind friendly.

    But the main point is – inflating green bubble and splitting it into 2 larger green (or even worse – red) bubbles is redundant and evil. Somehow this simple truth is forgotten frequently.

    And that’s why there’s a programmer – he’s the one who is responsible not only for creating those bubbles but seeing, tracking and adjusting their size and color too.

    For the same reason – not always rich domain model is must. Instead of adding redundant stuff time could be used more effectively – focusing on usability i.e.

  • http://joshilewis.wordpress.com Joshua Lewis

    Ok, I understand now. For some reason I was getting hung up on the term ‘model’ and associating that (automatically) with the terms ‘domain’ and ‘object’.

    I think we’re lucky these days with tools like NHibernate etc (I don’t know EF well enough to comment) that allow us to turn our domain models into persistence models without intruding on the POCOness of the domain model.

    I think in some circumstances it could get complicated if your persisted state is not well represented in the public ‘interface’ of the class, but I guess these types of classes are more OO (more behaviour than state, tell don’t ask etc).

  • George Mauer

    There’s nothing wrong with adding behavior to your entities when you do this too. Matter of fact you absolutely should when appropriate.

    Operations such as account.AcceptTransaction(transaction) and account.CalculateCurrentBalance() are domain logic which should go on those very same anemic entities.

    I am very much intrigued by the whole CQRS thing, it seems very intuitive and I am completely on board with the benefits but let’s acknowledge that for better or worse it IS a dilution of the ubiquitous language. After all, a domain expert isn going to tell you “I get Mr. Charles’ account and if it’s delinquent apply a late fee”, not “I fetch the information for the account identified by the name ‘Charles’. If the screen reads delinquent then I issue a late fee command for an account matching this identifier.”

  • http://www.lostechies.com/members/bogardj/default.aspx bogardj

    @George

    I would contend that those entities then cease to be anemic once you start adding behavior :)

  • JasonBSteele

    @bogardj

    > I would contend that those entities then cease to be anemic once you start adding behavior

    So what do you do when new requirements start arriving after delivery? How do you introduce complexity after you have decided on a pattern that cannot support it?

    Where is your business logic in this pattern? Is it all done by services?

  • Pingback: ASP.NET Web API, MVC, ViewModels and Formatters | Jimmy Bogard's Blog

  • Pingback: POCO’s are allowed to have behaviour… « jflood.net