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.

This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.

20 Responses to The Anemic Domain Model Pattern

  1. Louis says:

    @Me Myself I:
    I support you wholeheartedly. In my world, the reality is that my application has several domain-specific customers. But their rules & workflow are very different. In this case ADM with an interchangeable services layer is the way I chose. Maintaining & deploying fine-grained services that differ for each customer’s business processes is far easier that having to bastardise the domain model to cater for each customer’s peculiars.

  2. Louis says:

    @Me Myself I:
    I support you wholeheartedly. In my world, the reality is that my application has several domain-specific customers. But their rules & workflow are very different. In this case ADM with an interchangeable services layer is the way I chose. Maintaining & deploying fine-grained services that differ for each customer’s business processes is far easier that having to bastardise the domain model to cater for each customer’s peculiars.

  3. Me, myself and I says:

    @Kishore: the sole purpose of existence of domain models is to handle complexity. A simple domain model is a contradiction in terms. IMO.

    @Charles Chen: I seriously see no point in considering a DM architecture having better discoverability than a TS/ADM one, even for skilled OO developers. In a DM architecture, you often have to understand not just the implementation of one particular class which you need to change, but also its contract, and the contract is most often defined in terms of other classes in the model. In cases where a TS/ADM architecture is in the right place, your anemic model is composed of DTOs, of which there isn’t much to understand – they have no contract. A transaction script/service, in such cases, is relatively independent, and easily undertstandable – more so than a family of coupled classes inside a domain model, of which each one may model only an aspect or a relation or some message handling of some business domain object.

    I find there’s another advantage of a TS/ADM architecture which nobody seems to recognize. With a DM, changes in the business logic affects your DM – i.e., it may require you to change its architecture, not just the implementation of one or the other operation, since there’s no one to one or a well defined one to many mapping from the problem domain to the solution domain. With TS/ADM, a mapping from one domain operation to one or many services is more often the case, while the data model (modeled by DTOs) tends to be pretty stable, if properly designed/designed to reflect the business reality. Which makes sense to me: business data doesn’t change that often, only business operations do. So having a TS/ADM architecture IME tends to isolate things that may need to change due to a business change into separate entities (services or groups of services used by just that particular business operation that changes). Which makes maintenance easier. I’m not talking from the books, I’m talking from experience.

    What we do, most often: use a TS/ADM architecture. Then, whenever some not so simple, non-trivial business logic needs to be implemented, make sort of a minimal sub-domain model for that particular piece of logic inside a transaction script/service class/service method. Since such a model is most often small and self-contained, and it models only one particular facet of some business object(s), it is a lot easier to comprehend than a full-blown domain model. I have yet to see a domain model which can’t be decomposed into mostly inert, infrastructure-like classes, and just a few tiny clusters of domain-related classes which make it easier to implement some business logic as a tiny domain model rather than a procedural-like transaction script. In most cases, IME, domain models linking everything there is to link into one huge, strongly coupled and interconnected model are most often plainly not justified by the complexity of the problem domain/solution domain they have to model. Then why give up the advantages of TS/ADM, even for the 90% of the parts of a problem where there’s no need for a DM?

    An example: we used to do and maintain a project management application. It allowed one to manage several projects at once over the same pool of resources, project planning, time tracking, costs tracking etc. Most of the application was CRUD. The only part which was more reasonably implementable as a domain model instead of transaction scripts was constraint checking and automatic, resource-driven planning. This was however a tiny part of the application, in terms of all the domain-specific objects manipulated by the application. Why then include the rest of the domain-related objects in a proper domain model, instead of a proper ADM, and doing sort of a micro domain model inside the services class related to project planning? I can’t see any other reason than a sort of snobbery.

  4. I think a decision to make a project scalable and loosely coupled can very well lead to using Anemic Domain Model.

    Some projects are designed from a perspective of a bunch of components talking to each other using data messages. Usually those data message contain no business logic in them and serve just as the data containers, leading to a service layer that operates with such messages.

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

  5. Colin Jack says:

    @Charles
    “the locus of control is contained within your core objects (even if the pieces of functionality are still implemented in services).”

    Good point well expressed and I agree that in a good domain model thats the case. However I also agree with Greg, in a bad domain model, which is what most people with little OO experience will create, this doesn’t tend to happen.

  6. Kishore says:

    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.

    http://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

  7. Anders says:

    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?

  8. Greg says:

    @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.

  9. 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? :)

  10. Charles Chen says:

    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

  11. Colin Jack says:

    @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.

  12. Frank says:

    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.

  13. Colin Jack says:

    @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.

  14. Greg says:

    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.

  15. Frank says:

    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?

  16. 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.

  17. Greg says:

    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?

  18. Chris Falter says:

    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!

  19. Greg Beech says:

    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…

  20. Colin Jack says:

    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.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>