Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid an anemic domain layer and still have rich validation and business rules

If you have a domain object, and you want to do something useful and central to that domain object's responsibility like ensure it is valid, you sometimes need to access the state of related objects in order to perform this validation.

How to avoid the domain object needing to call out to a Repository or Data Access Layer? You can't always walk the collection relationships, even with lazy loading, because of performance, and you often want to execute queries in the domain object. You can dependency inject repository implementation into the domain, but not really pure and complicates testing.

I've always relaxed things and allowed access out from domain to a repository using DI. I have seen no clear examples of how to have a 'pure' domain layer in a complex application which is not also anemic and has a service/application layer doing all the grunt and messing with what should be innards of the domain objects.

like image 771
Keith Patton Avatar asked Oct 07 '08 10:10

Keith Patton


2 Answers

  • If the object is a value object, it should be immutable and validated during construction.

  • If the object is a root aggregate, and that its own state is sufficient to tell you if it is valid or not, you could add a validation method on it, which cascades through the aggregation.

  • Lastly, and I think it is your main concern, if you need to access several related objects (that are not in the same aggregate) to ensure one of them is valid, you definitively needs to deport this logic in a specific validation service.

I really think that injecting services and repositories into entities are not the best choice. Creating dedicated services seems more appropriate, and I don't see why it will leads you to have anemic domain objects.

In short, if you can validate you object state without relying on services or repositories, let the object takes care of it, at the aggregate root level. When you need to query services or repositories, or when you need other entities, then strongly consider moving this logic outside the object.

like image 50
Romain Verdier Avatar answered Sep 28 '22 02:09

Romain Verdier


I answered a similar question just a few hours ago. The answer contains some guidance I use when a try to enrich my model with logic and behavior without making it dirty with dependencies to infra-tech related stuff. Having trouble putting real-world logic into the DDD domain layer

the answer also links to other useful resources.

Good Luck and feel free to mail me or ask me about DDD and avoiding Anemic models. It is a interesting topic where people tend to solve this in different ways.

like image 33
Magnus Backeus Avatar answered Sep 28 '22 04:09

Magnus Backeus