0

I understand the difference between a rich domain model and an anemic domain model.

An anemic domain model contains classes with state only i.e. the behaviour is contained in application services. I recently asked a few questions about rich domain models. I notice that the answerers usually (well always) appear to suggest "rich" classes that contain behaviour with no or little state i.e. there are local variables (passed to methods) instead of instance variables. They use state when they can benefit from dependency injection for testing (which is good). Simple types like strings; decimals; integers etc are usually local variables. My research and experience tells me that this could be because these simple types are not interfaces making them more difficult to work with from an automocking perspective.

However, when I read books they seem to recommend classes with state like this once: http://www.newthinktank.com/wp-content/uploads/2012/12/Object-Oriented-Design.png (notice that the state contains simple types).

Is there a pattern name for domain models where classes contain behaviour and little or no state? Is it considered an anti pattern like the anemic domain model is: https://martinfowler.com/bliki/AnemicDomainModel.html ?

Please see my question here: https://codereview.stackexchange.com/questions/164772/decimal-quantities-needed-to-meet-cost. Would you describe RobH's answer as being rich or anemic? i.e. his class contains state and behaviour, however I would expect 'Cost' to be an instance variable.

  • 3
    "Is it considered an anti pattern like the anemic domain model is: " Although Martin Fowler says Anemic Domain model is an anti pattern, There are many who prefer it (myself included). See this SO post stackoverflow.com/questions/23314330/… – Samuel Jun 20 '17 at 22:53
  • 2
    I usually agree with lots of things that Martin Fowler proposes, but with his "Anemic Models are bad" attitude he didn't convince me. His reasoning is that "it's bad because it's different from smalltalk/pure oop", which is a... not really valid way to do thing nowadays, with most languages becoming multiparadigm. – T. Sar Jun 21 '17 at 2:08
  • 1
    Agree with the comments here. Anemic domain model can be a good design. The argument against seem to basically be "it is not pure OO", which is not really a valid argument. OO is a tool, not a goal in itself. – JacquesB Jun 21 '17 at 7:38
  • 1
    The anaemic domain model is not an anti-pattern. It has its uses & as you're finding here, many experienced devs prefer it as a design solution. The only anti-pattern you are struggling with here is "best practice". To declare something is best practice is to say it is the only true way & all other solutions are wrong. There lies the path to dogma and stagnation. Functional programming, with its complete separation of data & behaviour, is as anaemic as it comes. If we'd all embraced RDM "best practice", we'd have closed off our minds to ever using FP ideas and that would have been a bad thing. – David Arno Jun 21 '17 at 8:50
  • 1
    @JacquesB A common saying from an old teacher was that "pure oop was just an abbreviation away from poop". I've never forget that. – T. Sar Jun 21 '17 at 13:14
2

It seems like you've confused rich domain vs. anemic domain with behavior objects vs. value objects. These are not different names for the same thing. These are four very different things.

  • Rich domains are full of business rules. It has a language of it's own that a domain expert would feel comfortable reading and expressing even if they aren't a programmer.

those contrast with

  • Anemic domains concentrate on manipulating state. They actually are rich domains in a bizarre way. But the business rules are all about updating the DB and the the domain language is SQL. That's wonderful if your domain expert is a DBA.

but neither of those are the same as either of these:

  • Behavior objects are methods that are clustered around either some state that makes them change together or simply the fact that they need to be moved around together. Some have no state at all and that's just fine. A nice handy bag of functions. What they had always better be clustered around is that they are used together. That they abstract an idea together. They should cluster around a single responsibility. Some behavior objects cluster around business rules. Not all.

those contrast with

  • Value objects (like ints, strings, stacks, queues, lists, and pretty much anything with getters) are bags of data that generally do not care about their values. They provide methods that expose their data or measure it in some way but they carefully avoid making behavior decisions based on their data.

Where you've gone wrong is you've somehow got the idea that a rich domain can't have value objects and that an anemic one can't have behavior objects. Which is just silly. Sure, using nothing but value objects makes it hard to have business rules (heck it makes it hard to do anything) but lovers of anemic domains certainly don't need to swear off behavior objects to keep their domain anemic.

Is there a pattern name for domain models that contain behaviour and little or no state?

Functional programming? I mean really, who told you this?

0

I notice that the answerers usually (well always) appear to suggest "rich" classes that contain behaviour with no or little state

That's typical of an anaemic data model. You have classes that define the data of the domain, and you have classes that define the behavior of the domain. "Rich" classes as recommended by Fowler are a mixture of both.

Statelessness is another matter altogether. A class that has state is a class where a value of one of its members can be changed after construction. If all members of a class are immutable then the class is stateless. It is therefore possible to implement an entirely stateless domain model by using only immutable classes, and I recommend you do that.

They use state when they can benefit from dependency injection for testing (which is good)

In my opinion in the proper implementation of the anaemic domain model the behavioral classes should be stateless. This is achieved through constructor injection. So when you say "they use state"--this is incorrect. They do have instance level members but they are not variable (i.e. they are immutable). The members may be primitive "simple types", but often you're right and they're interfaces.

My research and experience tells me that this could be because these simple types are not interfaces making them more difficult to work with from an automocking perspective.

Yes this is sometimes true. Simple types are a bit harder to auto-inject because unlike interfaces you'll have many instances of the same concrete type (e.g. String) and it's harder to distinguish between them, but usually there is some support for configuration like this in your DI container. In Java, Spring has the @Value annotation for injecting primitives from configuration.

In my opinion the domain model shouldn't depend on a DI library or container though. Simply define constructors for the dependencies to be injected, and have a composition root where the constructors are invoked.

However, when I read books they seem to recommend classes with state like this once: http://www.newthinktank.com/wp-content/uploads/2012/12/Object-Oriented-Design.png (notice that the state contains simple types).

That diagram shows a "rich" model where behavior definitions and data definitions are in the same class.

  • 4
    Stateless and immutable are not the same thing. – Andy Jun 20 '17 at 23:40
  • Please see my question here: codereview.stackexchange.com/questions/164772/…. Would you describe RobH's answer as being rich or anemic? i.e. his class contains state and behaviour, however I would expect 'Cost' to be an instance variable. – w0051977 Jun 21 '17 at 7:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.