Why Domain Driven Design (DDD) is so great

This article aims to describe why I think that DDD aids you tremendously in creating robust and flexible applications.

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).

It’s much better to start with the domain model as it’s seldom that you know all business requirements from start. If you start with the domain model you can test drive the model with your customer/client. Go through different scenarios and ask him/her what you think. By doing so you’ll find requirements that wasn’t know from start. Once completed you can build the database design. As you know got a much better understand of how and when the persistence layer is going to be used. As such, you know where you have to add relations, where you should use third normal form (3NF) and where you can but the child aggregates as a JSON string in a root aggregate column.

The repositories are used to abstract away all that knowledge. The calling layer should not have to be aware of if you are using table relations or have serialized child aggregates as JSON. That why the repositories are called an abstraction layer. And that’s where many developers get it wrong and thing that their OR/M is an abstraction, when it in reality just mirrors the database design.

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 πŸ˜‰

  • eriklott

    “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”

    Face palm. Please don’t model your database after your domain model.

    • Thanks for your mature comment. You might at least want to explain why you think that’s a bad idea.

      • eriklott

        Tongue in cheek comment – no insult intended.

        If a developer happens to be using a relational database for their application, some of your advice could get them into trouble.

        The database should not be modelled after the domain; it should be modelled after the data. Relations in the database are of the utmost importance… it is a relational database. Much like your app, a relational database should be modelled in an application ignorant fashion.

        Model your app and your database separately according to their individual and independent requirements. Let your app’s repository and DA layer provide the mapping between the two. If you have to favour one over the other, FAVOR the data! It will outlive your app 10 fold.

        • I do not agree. I’ve seen a lot of poorly designed applications just because they modeled the database first and then tried to fit the domain model after the database design.

          The problem with is really that the requirements are rarely known when the application development is started. If the developer begins with the domain model they can develop it, show it to the customer and refactor it. Hence when they start building the database they can do it properly since most of the requirements are known.

          With that I mean that relations may not required everywhere, nor would 3NF. Sometimes it’s much better to put child aggregates serialized as JSON or similar in a column in the root aggregate. It all depends on how the data will be used.

          Do note that I’m not talking about a single aggregate when I say domain model. i.e. I’m not saying that there should be a one-to-one mapping between each entity and table. I’m talking about all classes in the domain model.

          Just as you say it’s the repositories responsibility to map the entities to the database.

          As for the data outliving the application I’ve never experienced that in my 20 years as a developer. At least not without modifications being done to the current database design. So if the DB is going through changes, there’s really no difference from what I’m recommending.

          • eriklott

            “We model our database after domain model”.

            I was reading this as ‘We model our database’s structure to match our domain model structure’, rather than temporal ‘after’. My bad.

            Yup, I agree: domain first, datastore second.

          • David Graham

            I think you go into the project modelling the domain, then you model the database, then you go back to the domain (it’s like a spiral). You’ll formulate a unique new domain that satisfies the original “pure client’s domain” and the database. All this spiraling is done before you start to code. But I tend to agree that the application needs to gear more towards the data then the “pure client’s domain”. For example, you are going to need IDs to do things well throughout the app. Many customers don’t attach IDs to parts of their domain. Plus there’s an old truth that the real world just doesn’t fit into OOP all the way. Once you do get an OOP plan, I see people attempt DDD and build these objects that have to be hydrated to be used, and sometimes you just need to pass around IDs (you’ll still use good OOP though). I think the big concern is centralizing actions. Give entities the properties and methods they need, but don’t refrain from giving them abilities to work with just their IDs. You might end up with 2 types of validation/rules techniques, for single persistence or big, bulky id-based persistence. If a new developer comes on board, he’ll need to use the entity and methods provided, or study them to see how he can add a new method and ensure the rules are kept. Articles like this tend to make it seem so easy, but it is a hard time ignoring the database and performance concerns. Just my 2 cents, not worth much. πŸ™‚

          • BBI

            OK, as long as domain designers don’t dictate the database structure. Non-Normalization (denormalization requires normalization first!) and JSON or XML trashbin columns suggest exactly that. Of course it’s ok to deliver denormalized or document data to clients (e.g. using database views or properly designed SQL queries, ORM mappings and JSON/XML generators), it should just not be stored that way internally

            Once domain design forces such DB structures, the relational database becomes a trash dump. If you want to get rid of the relational DB entirely, go for NoSQL instead!

  • Maciej

    Nice article, clears some of the doubts for DDD newcomers, thanks !

  • Leon Stewart

    Just found your site… Great article!
    Thanks!

  • Lau Berghea

    Reading your article made feel a little better: I’m trying to make DDD part of a process of rewriting one of our projects but I don’t have too much luck, as I don’t have the experience to take on the job by myself – or to be convincing enough, as I also face a strong resistance from my coworkers who see my DDD ideas as “useless overthought baggage” and who think the Domain Layer is just a series of data structures being passed around (the anemic domain antipattern, it seems, according to Martin Fowler) -( However, I had been exposed once to DDD in real life a few years ago and I know how much sense it makes and I was amazed by its… if I may say, beauty !
    Anyway, I have a quick question, please: having failed (after several solitary attempts) from a designing/programming perspective to include a Domain Layer to the new project, I started to wonder if the concept is simply just not suitable in this case ?! Finally, to phrase the actual question: do you think that DDD could still be used/followed even when dealing with old/existing databases ?

    • If DDD should be used or not should not be decided by the database design/size/structure. DDD do actually not care about the database at all. The DB is just an implementation detail which is abstracted away by the repository pattern.

      Whether DDD should be used or not should be decided by the application complexity. How do you determine if the software is complex then? That’s a whole chapter. On a spectrum you can but CRUD applications in one end and DDD applictions in the other. A typical CRUD application is a registry editor while StackOverflow can be seen as a typical DDD application (when you write a question a lot of business rules are processed in the background, and you got different moderator UIs with their own rules).

      Read my protect your data article to understand the difference better: http://blog.gauffin.org/2012/06/protect-your-data/

      • Lau Berghea

        Thanks, jgauffin. I gave it more thoughts and I realized that my dilemma had two sides that I was mixing together: the Domain and the Repository/DataMapper. Let me explain myself a little: I had only been involved in DDD in the past for a very Code-First project where the domain classes were becoming, via a generic repository and mapping files for NHibernate, data ready to be stored/retrieved. New tables were created on the fly automatically by the app, as our domain implementation was growing. The only focus/work on database side was in keeping the (xml?) mapping files up-to-date; NHibernate was doing everything else for us. Anyway, this time, the scenario is a bit different: we’re rewriting a large old project and the main requirement is to keep using the existing database (without changing it) – the two systems will even run in parallel for a long time, as we’re replacing module by module and not the entire thing at once. Now, my main problem was to find the way of following DDD while taking advantage of Entity Framework for relieving us from CRUD and, also, have a smart Repository/DataMapper to connect the two (“smart” as there are cases when the structure of Domain classes would differ so much from the data structure as predefined in database. eg: a simple Address/Location object would require about 5 tables to be joined on soft foreign keys with added logical references to all kind of AddressTypes, EntityTypes, AddressClasses tables etc, etc. The same tables are also the place to go for email accounts, phone numbers, personal websites, social networks accounts, etc).
        Anyway, my problem, derived from all the above factors, was that I was mixing up multiple concerns: domain, repository, data access, etc. and trying to solve them all at once. I realize now what you’re saying: the domain is only supposed to reflect the business rules and I could design&create it 100% without even thinking about what’s around it (databases, UI, etc). The biggest challenge for me remains now the Repository/DataMapper but, at least, I’ve taken out one big piece that I’m not worried about anymore: the domain.
        I’m writing all this for few reasons: to put my thoughts in order I guess, to confirm that I understand your point and, why not, to help others that face similar challenges to find the answers to their questions.
        Thanks again for taking the time for this discussion and I’m sorry if my post turned out to be too long.

  • BBI

    Interesting to read this, since this kind of thinking obviously messed up systems and databases I am currently working with.

    Relational databases have their own, rather “scientific” design concepts, such as relational integrity and normalization. It’s wrong in general, when database design is dictated either by client or domain designers.

    So I got some painful experiences with relational databases turned into trash dumps, just as mentioned here: Unnormalized data structures (not “denormalized”, because this would require them to have been normalized in the first place), omission of relational integrity (foreign keys) and first normal form, with compound data in single columns, down to JSON/XML trashbin columns, for which the database is blind (no, XML capabilities of most current databases are not being used). Database structures dictated by customers, client and domain designers.

    Actually, relational databases and ORMs can abstract such demands, using views or specific SQL queries, so the internal data structure is still correct and not an unnormalized JSON/XML mess. But this was not desired, it was demanded that database tables look like business objects, effectively turning the database into a trash dump, as described here. Mainly because nobody wanted to dig deeper into database and ORM topics, just use entities like normal code objects. (plus, many ORM add complexity, instead of making data access from code easier).

    Of course, over time, this created more and more inconsistency related bugs and performance problems, for which the response was to copy the data around into other tables in client specific data formats – of course, making other things worse and obstructing the way back to correct data.

    Applying domain driven design to relational databases themselves seems to me like a recipe for disaster. It’s ok if an intermediate layer generates domain specific data formats, but domain and business object designers should keep their hands off the database schema!

    Some solutions could be:

    – move away from relational databases to NoSQL, of course giving away the advantages of the relational DB, such as data consistency, having to code this in the applications. Anyway, a NoSQL database is much more suitable for this than a relational database, abused against all relational design rules and turned into a trash dump.

    – my idea: formulate business rules as expressions, rather than procedural code, from which they can be translated into anything: SQL queries, classic procedural code or even something exotic, such as GPU instructions. Expression- based languages (Lisp?) or C# LINQ look great for this purpose!

    • What you basically are saying is that sloppy design hurts, right? I fully agree with you there.

      Using a column to serialize child aggregates is not really the problem, but doing it without fully analyzing the consequences. Sometimes it’s justified, sometimes it’s not. It depends on the type of application, how large it is, complexity etc.

      So the serialization itself is not a free ticket to forget all about what we’ve learned about dealing with data structures.

      • BBI

        Whatever the database structure is, it should be created by database designers and not domain, business object or client designers.

        A common problem with relational databases is unstructured data, or data with rapidly changing schemata.

        In fact, it’s mostly not possible to define all data and metadata in a great upfront planning. The most common (and problematic) solutions to this are Entity-Attribute-Value (EAV) tables and document (mostly XML or JSON) columns. The last are basically NoSQL within SQL. You can use full text indices or database XML (don’t know about JSON) capabilities, such as indices and queries with XPATHs.

        It is, however, a dangerous slippery slope: once you design EAV or document tables, demands will increase to use these instead of regular data tables, because they are much easier to design and release in the first place. This may result in client applications only designed to use EAV/document data, and a management forcing relational DB designers to use triggers or app code to copy data from “real” tables into EAV tables or document columns, so the clients can use it (adapting them to read real data would take SOOOO much more efforts).

        And, of course, when a new feature request comes in, nobody can foresee what the data is to be used for. They will all assure that the data is “client only” and that the database can be blind for it. But then, after a few days, weeks or months, demands trickle in to search business objects by EAV/document stored properties. And the database is messed up.

        Of course, document columns also degrade database performance: Instead of a few small value columns, you suddenly need a whole NCLOB/NVARCHAR(MAX) or equivalent column, taking much more time and bandwidth to load. And ORMs tend to load all business objects completely, making subsets of properties (with exclusion of XML/JSON docs) more difficult.

        I think there are acceptable solutions to these problems. But parts of your text suggest that one should omit relational design (while using a relational DB) and sacrifice it for simple, business-oriented design. This is a very serious problem coming with the DDD paradigm, not only in your post, but for many who attempt to get rid of the rather tight rules of relational DB design. I write this after seeing systems, still based on relational DBs, which look like a 10 year old playing around with SQL Server Management Studio.