Greg Young [MVP]

Sponsors

The Lounge

News

Advertisement

The Anemic Domain Model Pattern

OK so I assume that you have run into the Anemic Domain Model Anti-Pattern at some point or another likely here on the bliki.

To quote from the bliki

The basic symptom of an Anemic Domain Model is that at first blush it looks like the real thing. There are objects, many named after the nouns in the domain space, and these objects are connected with the rich relationships and structure that true domain models have. The catch comes when you look at the behavior, and you realize that there is hardly any behavior on these objects, making them little more than bags of getters and setters. Indeed often these models come with design rules that say that you are not to put any domain logic in the the domain objects. Instead there are a set of service objects which capture all the domain logic. These services live on top of the domain model and use the domain model for data.

What if I were to tell you that there are times and places where gasp an anemic domain model were in fact a best practice that would be highly recommended to a team? I really do vision the pitchforks and torches coming at me when I say this … Many including myself have lambasted unmentioned groups for pushing people towards anemic domain models so ….

 

Making the case

To start with let’s analyze why you were using that domain model in the first place. Ideally you were using it because it provided you the benefit of being able to effectively handle more complexity as opposed to a system like active record or transaction script. In other words you found your system was too complex to be modeled in a more procedural way. This complexity is often seen by analyzing the duplication of code in your more procedural transaction script based system.

Of course I find it rare to hear people cite this as why they are using a domain model. The reasons I hear tend to be more focused on the layering that necessarily comes with having a domain model. Instead I hear reasoning like testability, maintainability, abstraction from persistence mechanisms, strongly defined contracts etc.

Where am I going with all this what happened to the anemic domain model pattern? Well it depends why you wanted a domain model in the first place. If you are using a domain model in an object oriented way to help you in the managing of complexity it is absolutely an anti-pattern for you to be seeing an anemic domain model. What if you are in the IMHO much larger group that is mainly seeking the benefits that come with a domain model in layering?

The simplest in me would say that we would need to then compare the anemic domain model with other mechanisms to see if it would derive any benefit. We can pretty easily gain over a classical Active Record pattern because we can better express what is happening (especially in cases where we have an existing data model as we can map the data model if we want to). This leaves us with the more interesting case of transaction script, I deem the case “interesting” as both models are in fact transaction script we are comparing transaction script over an object model vs transaction script over say table module.

I would say that even in this close distinction that the anemic domain model can have some advantages. At the least single property level validation tends to be encapsulated within the object.  This although really a slight step towards having a functional domain model can offer huge gains in terms of dealing with transaction script where all of the validation is distributed. There can however be other advantages such as the ability to more easily test in isolation and the long term maintainability of the system.

 

Defining a context

So the real question becomes can we define a context where purposefully creating an anemic domain model would be a good idea over our alternatives?

We want a layered architecture. We understand that our application due to non-functional requirements will need the benefits that a layered architecture provides. We understand the cost of creating a layered architecture and it has been justified by the stakeholders of our project.

Our domain is not extremely complex. This is a bit of a misnomer, but let’s say that our domain falls within the bottom 90% of systems in terms of domain complexity. There are likely some spots of higher complexity that we may focus more on (and perhaps even model in a more object oriented way).

Our team is not highly functional in object oriented design and analysis. When I say this I mean that team members must be highly functional in order to attempt creating a domain model (all other attempts will be doomed to failure, likely as an anemic domain model). When I say highly functional I would consider the AJM model (and people at the least being journeyman with maybe a single apprentice as the complexity of the system increases the number of masters needed increases). Said bluntly, 90% of teams in the Microsoft world should be looking at building anemic domain models as opposed to actual domain models for solely this reason. Using things that the development does not have a large understanding of is a certain recipe for failure.

We would otherwise consider a simpler model such as transaction script but feel that we can benefit from things such as further testability.

 

I believe that using these five viewpoints we can effectively create contexts within it makes perfect sense to be choosing to create an anemic domain model.


Posted Wed, Jul 15 2009 4:10 PM by Greg

[Advertisement]

Comments

Colin Jack wrote re: The Anemic Domain Model Pattern
on Wed, Jul 15 2009 4:24 PM

Couldn't agree more, a topic thats not often discussed and I can't argue with a word. One thing I'd add, use anemic domain if you have little access to domain experts e.g. if all you have are system experts or proxy domain experts. Trying to use a domain model in those situations invariably results in a lot of wasted effort creating a model that you realize is utterly wrong after 5 minutes with the domain expert.

Greg Beech wrote re: The Anemic Domain Model Pattern
on Wed, Jul 15 2009 7:25 PM

What's this? I'm astounded! Is CodeBetter actually publishing a blog post that actually has some roots in the real world? And isn't just full of TDD is the One True Way crap?

Well done. I may come back here more...

Sanjeev Agarwal wrote Daily tech links for .net and related technologies - July 14-17, 2009
on Thu, Jul 16 2009 3:27 AM

Daily tech links for .net and related technologies - July 14-17, 2009 Web Development ASP.NET Membership

Chris Falter wrote re: The Anemic Domain Model Pattern
on Thu, Jul 16 2009 11:42 AM

Greg - I do find the perspective refreshing.  I'm having a hard time understanding some of it, though, as you appear to have been in a big hurry when you were writing.  For example:

"This leaves us with the more interesting case of transaction script, I deem the case “interesting” as both models are in fact transaction script we are comparing transaction script over an object model vs transaction script over say table module."

Every word in that passage is in an English dictionary, but I don't think we could classify it as an English sentence.  Could you reformulate it, please, so we can better understand what you're trying to say?  Thanks!

Greg wrote re: The Anemic Domain Model Pattern
on Thu, Jul 16 2009 12:12 PM

Chris ...

it is "interesting" because ... although the "anemic domain model" is called a domain model. It is not really a domain model at all it is in fact transaction script.

As such we are comparing transaction script to transaction script. The anemic domain model being transaction script over an object model compared with a more classical transaction script over say table module.

Make sense?

Think Before Coding wrote re: The Anemic Domain Model Pattern
on Fri, Jul 17 2009 5:41 AM

For sure it's better to have a model even if anemic than no model at all !

It gives a better view of data organisation for transaction script-like code.

Frank wrote re: The Anemic Domain Model Pattern
on Tue, Jul 21 2009 5:39 PM

Just for my education, based on the comment of Colin.

"Trying to use a domain model in those situations invariably results in a lot of wasted effort creating a model that you realize is utterly wrong after 5 minutes with the domain expert."

What kind of pros does an anemic domain model have over a domain model when the model itself is wrong anyways?

Greg wrote re: The Anemic Domain Model Pattern
on Tue, Jul 21 2009 5:44 PM

if I can pout words in Colin's mouth its because you never spend the time to try to no9t make it anemic ... its is just a data model. So you would get the beenfits of isolation and abstraction but not waste any time trying to figure out a real model.

Colin Jack wrote re: The Anemic Domain Model Pattern
on Tue, Jul 21 2009 6:16 PM

@Greg/Frank

Exactly. If you use a proxy domain expert you'll spend a lot of time/effort in analysis and knowledge crunching and getting that warm fuzzy feeling, then 10 minutes with a real domain expert and you get the breakthrough that shows your original model was all wrong. Then you get the joy of basically dumping, or extensively redesigning, your model to fit the real world.

In comparison if you'd just gone anemic the redesign is simpler, you just have simpler data structures and services which are much more malleable in those situations.

Frank wrote re: The Anemic Domain Model Pattern
on Tue, Jul 21 2009 6:35 PM

Then - if I understand correctly - there isn't much difference between a faulty domain model and faulty anemic domain model, as long as you don't spend enormous effort in the model at all.

Colin Jack wrote re: The Anemic Domain Model Pattern
on Sun, Jul 26 2009 4:44 AM

@Frank

Yeah, if you spend a lot of effort on a fault domain model then you face a more difficult job re-engineering it. However if the model was simple and/or you kept your solution simple then either can be refactored/redesigned easily.

Charles Chen wrote re: The Anemic Domain Model Pattern
on Tue, Jul 28 2009 9:51 PM

I think you've missed one point here that argues strongly against a transaction script/anemic domain model: "discoverability".  

While codebases written in the style of DM or TS/ADM will probably contain the same number of classes, there is a big difference in how those classes are wired together and how much _surface area_ a user of the codebase (let's call it an API) will need to know.

One of the key benefits of a domain model approach is that it hides the complexity of the different components behind the core objects of the problem domain.  I like to think that in a transaction script/anemic domain model, the locus of control is placed outside of your core objects.  In a well designed domain model, the locus of control is contained within your core objects (even if the pieces of functionality are still implemented in services).

Take a calendaring application for example.  In a TS/ADM implementation, you'd have something like this to move an event (in C#):

// What you would expect to see in a TS/ADM

Event _anExistingEvent = ... ;

EventScheduler scheduler = new EventScheduler();

scheduler.MoveEventDate(_anExistingEvent, DateTime.Now.AddDays(1));

In contrast, what you would expect to see in a domain model approach:

Event _anExistingEvent = ... ;

_anExistingEvent.MoveEventDate(DateTime.Now.AddDays(1));

The difference is subtle, but there is a huge gain in usability as there is one less class involved in the interactions of your domain object; a user of your API/framework (i.e. your coworker) doesn't have to learn about the EventScheduler to use your code.  Likewise, if we consider the other things that we can do with events, we start to see the benefits of encapsulating (or rather) hiding the business logic and complex interactions within the domain object instead of in external services.  For example, imagine another scenario where you want to send an event in an email:

// TS/ADM style

Event _anExistingEvent = ...;

string _serverAddress = ...;

EventSendingService service = new EventSendingService(_serverAddress);

service.CreateMessageForEvent(_anExistingEvent);

service.Connect();

service.SendEventMessage();

// DM approach:

Event _anExistingEvent = ...;

_anExistingEvent.SendEventMessage();

Now I'm not implying that there is any less code in the implementation, but if we consider this code from as a public API intended for use by others, clearly, a domain model approach is much more usable and approachable than a TS/ADM approach where a user of the API has to know many more objects and understand how they are supposed to interact.

Just my input :)

-- Chuck

james peckham wrote re: The Anemic Domain Model Pattern
on Fri, Jul 31 2009 12:59 AM

I don't know if this is what you're experiencing with an anemic domain model but general speaking our webservice contracts and operations are  so abstract that every ui that is built on those models requires  tons of code to bring it in line with LOB desires. It makes me wonder if there's any value to having built the model anyhow? :)

Greg wrote re: The Anemic Domain Model Pattern
on Fri, Jul 31 2009 12:24 PM

@Chuck I think we can safely put discoverability as a non-functional requirement. Is it always needed?

Also I would point out that the discoverability is only there in a domain done by people who really understand OO which is imho less than 5% of people in the .NET space and probably in the low 2 digits in the java space. When not done properly OO actually hurts discoverability over more procedural styles that people are more familiar with.

Anders wrote re: The Anemic Domain Model Pattern
on Thu, Aug 13 2009 2:58 PM

Any suggestions on where to start if you want to move away from an anemic model to a richer one? Would you start within your transaction boundries and let then help you define your aggregates or would you have another approach?

Kishore wrote re: The Anemic Domain Model Pattern
on Thu, Sep 10 2009 10:30 PM

All,

I agree, I've been using the Anemic Domain model for a while now and do prefer it for many of the reasons listed:

1. Separation of concerns.

2. Facilitates Code Generation

3. Facilitates "Enterprise-Level" integration

4. Logic placed in Services can be easily switched.

5. Note: Extension methods in 3.5 can allow for an interesting hybrid between the two.

6. Domain Model's can become complex.

7. Relationships / Aggregates can still be in the Anemic Model.

Regarding #6 Above think of all the various "Services"/Functionality that can go into a Rich Domain Model.

1. Security

2. Validation

3. Data Massaging

4. Persistance

5. Import / Export

6. Serialization

7. Event Handling

8. Resource/Localization

This can easily get quite complex.

I'm using the Anemic Domain Model and various re-usable components that are part of an open-source library I'm building. And so far this approach is working quite well.

commonlibrarynet.codeplex.com

Finally, I just want to say.... simply put.. things change. And what may be good in one-scenario may not work in another. Patterns change them selves.

Regards,

-Kishore

Jimmy Bogard wrote Persistence model and domain anemia
on Thu, Dec 3 2009 1:26 PM

Domain anemia is a term thrown around like it’s a horrible disease.  However, a while back, Greg

Add a Comment

(required)  
(optional)
(required)  
Remember Me?