Why Domain Driven Design (DDD) is so great
Today we got several cool frameworks and libraries that we can use. ORMs, WCF, ServiceStack, SignalR, WebApi, IoC etc etc. Just thinking of all can make any serious developer go crazy of joy.
All those tools is so great that we almost canât wait to use them. Here is a typical conversation with a customer:
Customer: I want to create a forum
You: Oohh ohh, wait! Yeah. I could use Sharepoint. No no. Itâs so bloated and slow. oh oh! I got it. wait! SignalR+WebApi and KnockoutJS. So cool! Letâs do that!
Customer: But but. We just need a basic forum.
You: Shut it! Me wanna do SignalR
And so on. My point is that itâs so easy to forget that we should focus on solving a problem for the customer and not on which technology we should use.
The role of the database
A couple of years ago we said that we developed database driven applications. Erhm. Maybe a bit more than a couple of years ago, Iâm getting old. It was the shit. If you said to a DBA that you have normalized the DB according to 3NF he would probably have gotten an orgasm. Today the whole look of applications as data driven has gotten so widely spread that most applications are today modeled according to the database model and itâs relations.
The problem with that is that the database forces you to couple your application thanks to all DB relations. It also forces you to model the business layer after the DB model. Especially today if you are using an OR/M.
Database centric applications usually lead to CRUD influenced UIs. That is that you show a big fat screen saying âGo ahead an edit the fields you want. I trust that you have full knowledge of which combinations of changes that are valid given the current state of the objectâ. Thatâs also a huge problem. Business rules are hard to test since itâs the user that enforces them. It will undoubtedly lead to that you have to go into the database and fix things: âHey, itâs me the customer. Order XX have the field Y set to Z. That shouldnât be possible, can you fix that?â. Those kind of bugs are very hard to locate and therefore fix.
Enter DDD
Domain driven design is all about understanding the problem that the customer is trying to solve. During the initial phase you donât even think about architecture or programming. Your prime goal is to understand the business, all terms that customer uses and how he models the domain. The customer is in fact the architect. He might not draw everything, but he guides you and tell you how everything should be modeled.
So what you do is sitting down with the customer and discuss each business case. You listen to him and draw something which the customer can understand (read: NO UML). Then you use all of those sketches and notes to build the model = code.
Coding
In DDD you shouldnât care about persistence, UIs or anything else. You just code vanilla classes which represents the model that the customer described. And since you just have POCOs itâs incredibly easy to test everything. I highly recommend that you try to use a TDD inspired approach together with DDD.
In DDD every class in the model should always be in a consistent state (i.e. being valid). That means that youâll have no (or a very few) public setters in your classes. Instead you have methods in each class that represents an action that the customer described. If one or more classes (entities) are involved in an action youâll create a new class which coordinates the work for the both entities (that class is called a service). Read this if you would like know more about how private setters affect your application.
Using methods also means that we canât have CRUD UIs but instead have to code task based UIs. Itâs hard when you come from CRUD type of applications, but the task based UI tends to become a lot less cluttered when you get used to coding them.
Finally you have a nice domain model where all business rules are encapsulated in your classes and hopefully tested with unit tests. The likelihood of bugs like the ones I described for CRUD applications are a lot less.
The event
Each time something happens (something that the the customer described) in a DDD application there is an event generated. These events allow you to create a more loosely coupled application.
For instance when a new users registered an UserRegistered event is generated. It can be subscribed to by an NotifyAdminOfNewUser handler or a SendAnWelcomeEmail handler. Or both. The point is that any part of the system can handle any event. You can even create a module/plugin based application where the plugins handle each others events. How cool isnât that?
Persistence
Most people which have a hard time with DDD have it because they start at the wrong end. They start with the database and then try to fit the domain model according to the db model. Thatâs the wrong approach (which there of course are solutions for, but thatâs out of the scope of this article).
So now you got a solid domain model that would kick a CRUD butt at any time. Itâs time to think about persistence. We model our database after domain model. And this time the relations in the database isnât that important since the database is just storage now. The database is driven by the domain model. Changes in the domain model is persisted to the database with the help of repositories. Itâs the repositories job to make sure that there are no stray data in the database. Thatâs also easy to test using integration test and just push data through the repositories.
This new point of view also allows us to separate the data model into several data sources if we would like (since the data is decoupled in your domain model). We do not have to use one database normalized to 3NF. We can use one big denormalized database (disk space is so expensive, isnât it?) or even web services in our repositories.
The UI
Now that we got some data and a domain model itâs time to start create the UI. Again we model it after the domain model. Since itâs dictated after all methods that we got in your domain model itâs quite easy to know how we should structure it.
Outsourcing?
When youâve modeled the domain model itâs fully possible to let others take care of the persistence and the UI. Just send them the domain model. In fact, you could even let two different teams take care of it. One that builds and optimizes the data layer (caching, db etc), and one that builds the UI.
Let the original team (the domain experts) continue with the next project (or iteration if youâre agile).
Conclusion
Thatâs why I love DDD.
Reference: Why Domain Driven Design (DDD) is so great from our NCG partner Jonas Gauffin at the jgauffin’s coding den blog.
