Anyone who's been reading this blog for a while may know that I've always been a proponent of what I used to call a "rich Domain Model". To get a feel for what I was referring to when I talked about a Domain Model check out the following posts:
Domain Driven Design has caused me to put some further thought into the topic. I've always wanted everything wrapped up in my domain objects. Rather then dealing with managers and domain objects and trying to decide what belongs where I always liked having everything packaged up in a nice rich domain model. I was so attached to this approach that even after reading through DDD I was still in this camp. It took a couple email's to the DDD mailing list for me to realize I had made the chapters in DDD say what I wanted, I made them read as if what I was doing was what was recommended. This caused me to go back and re-read many of the chapters in DDD which helped me realize that the recommendations that were being made were much more in line with what I had called the Manager model in the past.
Fortunetly for me I don't totally distort everything that was said in the chapters. DDD does advocate a rich domain model, just not the type of rich domain model I had been using.
Before reading DDD my domain objects had the following responsibilities:
- Used DAL layer to retrieve items from the data store
- Had deep relationships with other objects in the model.
- Contained domain logic relevant the the real world object being represented by the domain object
- Were used to retrieve single instances as well as collections of domain objects
After reading DDD my domain objects become a little simpler and give up much of their responsibility. Rather then concerning themselves with multiple responsibilities the role of the domain object (Entity) is simply to model the real world object's data and behavior. Some of the responsibility previously contained in my "rich domain model" has been moved out to Repositories. Repositories take on the responsibility of returning objects from a data store. They handle returning single instances of objects as well as collections of objects. To ensure the repositories don't start taking on too much responsibility we introduce Factories. Factories take data retrieved and turn them into actual domain objects. Often times we have a coupling between our Repository and a Factory. To ensure the two are loosely coupled I recommend the Factoring be configured using Dependency Injection. This allows any Factory to be "inserted" into the repository and ensures that none of our objects are coupled to one another.
As you may be able to see, my view on the wonderful world of domains has changed pretty significantly. By moving much of the responsibility out of the domains and into other objects that can better handle the responsibility we're able to creating more flexible domain models. Rather then gradually creating gigantic domain objects with all kinds of dependencies and way too much responsibility we create a set of components that make up our rich domain model.