How Domain Driven Design changed my way of thinking

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. 

 

# re: How Domain Driven Design changed my way of thinking

Thursday, September 16, 2004 4:47 PM by MichaelOnTarget    
I agree with you.

Also I think that O/R Mapping tools help in separating domain objects and related objects (factories and things like that). For example, NEO framework ( <a target="_new" href="http://neo.codehaus.org">http://neo.codehaus.org</a> ) has very good features for such separation.

&gt;&gt; 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.

Yes, that's exactly what I thought.

# re: How Domain Driven Design changed my way of thinking

Thursday, September 16, 2004 5:51 PM by Frans Bouma    
Michael: agreed that some low-level logic/behavior should be placed inside the entity. The problem starts when business logic rules spans more than one entity. Where to put that logic then?

# re: How Domain Driven Design changed my way of thinking

Thursday, September 16, 2004 9:11 PM by MichaelOnTarget    
&gt;The problem starts when business logic rules spans more than one entity. Where to put that logic then?

It depends. Could you give examples?

# re: How Domain Driven Design changed my way of thinking

Monday, October 15, 2007 4:31 PM by Fuzzelogic    
Hey!.
ok so you say ..'the role of the domain object (Entity) is simply to model the real world object's data and behavior'
Now what is the behavior you refer to. eg. Customer Object.
the data is things like Name, Tel, RegionCode. The behavior (WOULD HAVE been) Save, Update,Delete. What is it NOW..

Thanx

# re: How Domain Driven Design changed my way of thinking

Tuesday, September 09, 2008 6:41 AM by Lyronne    
To comment. My entities don't have a save method. just a delete. Entities are served up by repositories, the repositories plug onto an abstraction of factory to create objects from the underlying data. Each object has a state, New, Dirty, Existing, Deleted. Objects are not saved explicitly. rather a UnitOfWork object keeps track of all object states and calls the appropriate Insert,Update,Delete method on an abstraction of the Repository based on the object states when changes need to be persisted.


So code looks like this
UserId userId = UserId.Parse(txtUserId.Text);
UserRepository userRep = runtime.ObtainService();
User user = userRep.GetUserById(userId);
user.AddSkill("C#");
user.AddSkill("F#");
UnitOfWork.Current.Commit(); // new skills are added
user.Delete();
UnitOfWork.Current.Commit(); // user is deleted
User newUser = userRep.NewUser("Lyronne");
UnitOfWork.Current.Commit(); // new user is saved

Post a Comment

 
 
Prove you're not a spammer: 
5 + 5 =