Getting deeper into DDD
Practical information on Domain driven design seems hard to come by. The DDD bible is technology agnostic and other books on the topic are meant for .NET audiences. Even these books are not exactly easy reading.
To learn about one view of DDD, I have consolidated some information from Udi Dahan's blog. All of the following content is actually his writing or response to his readers, in a more digestible format. For a detailed explanation, you can always refer to his original articles.
From http://www.udidahan.com/2009/06/29/dont-create-aggregate-roots/
Aggregate roots should *not* be created. Always get an entity.
Don’t add any objects to the session or unit of work explicitly – rather, have some other already persistent domain entity create the new entity and add it to a collection property.
Don’t go saving entities in your service layer – let the domain model manage its own state. The domain model doesn’t need any references to repositories, services, units of work, or anything else to manage its state.
Almost every activity that results in the creation of an entity or storing of additional information can be traced to a transition from a previous business state. In any transition, the previous state is the aggregate root.
An aggregate root depends on the use case. An object can be an aggregate root in one use case, but not in another.
If your service layer is newing up some entity and saving it – that entity isn’t an aggregate root *in that use case*. Aggregate roots aren’t a structural property of the domain model.
Domain objects need to maintain their *business validity*. Not accepting dates before today falls under that definition. Strings less than 50 characters in length does not.
Rarely should entities actually be technically deleted, if ever. The better option is to change some kind of status on the entity.
Harness the technique of fetching strategies to get the best performance out of your domain model by representing your use cases as interfaces on the domain model
How do you unit test the code that depends on the ORM? Do you abstract it?
The only code that depends on the ORM is the service layer. The domain model doesn’t depend on anything other than itself – and it’s the thing you’ll be unit testing.
It makes sense to test the domain model, of course, but it also makes sense to test the service layer to make sure it is orchestrating things correctly, no?
The service layer shouldn’t orchestrate – after getting a domain object or two, it calls a single method on one of them, that’s it.
From http://www.udidahan.com/2009/01/26/altnet-ddd-podcast/
One way of getting rid of multiple constructors is by making use of the repository to create methods for the various cases. But analyzing further, what’s going on here we understand that, say, the way the order is created is dependent upon who the user is. It looks like user, or customer, is our aggregate root. Thus, rather than our service layer calling a method on the repository, we first get the user object by id, then create the order.
Having polymorphic aggregate roots is very useful and broadly applicable.
The dependency inversion principle doesn’t provide much value within a domain model. Domain model objects are designed to collaborate with each other intensely in their implementation of business rules. They should not be talking to anything else outside the domain, thus there is no need for DI in there.
Separating a system into bounded contexts simplifies the code greatly. The understanding that accepting an order and fulfilling an order require different logic, different data, and thus, different domain model objects is DDD at its finest.
Often, the best way to extend a system is “around the edges” by adding an additional bounded context. Domain objects are free of this concern.
The repository interface is part of the domain, however the implementations are infrastructure concerns. Still, objects in the domain model don't need access to repositories.