Domain Driven Design in a Nutshell

This is a brief summary of what domain-driven design is and what are it’s building blocks, it is meant to serve as a quick reference for DDD, for more detailed information:


Domain Experts

Those are the individuals who have a great deal of familiarity with the domain which the software is trying to solve a problem for. For example, if we were making a software for medical information, then the doctors would be our domain experts, if we were making a software for hotel reservations, the hotel managers would be the experts of this domain.

They are the ones who carry the knowledge which defines the problem and what the output of the software should be in order to be considered a complete solution, and they can define acceptance tests for this software

Ubiquitous Language

The Language: Languages are some set of characters/phrases arranged together to define a meaning that is understandable by someone or something that can parse those phrases. When developing software it is important that the domain experts and the developers would create a language of expressions and common phrases that define the system’s model and interactions.

For example, in a hotel booking app, the term a Booking would be an agreed upon term that is both understandable for both the experts and the devs, whenever any of them needs to exchange a piece of information about booking manipulation, they would use the term a booking, also when a user books a booking we use the term books to refer to this activity.

The Ubiquitous language MUST be used as it is in our code. Developers are not allowed to change the terms to more technical one, like using BookingTable or BookingEntity. It must be the same language used when communicating with the experts and the language that the experts would understand. The same goes for the activities or the interactions which our objects do, those interactions need to be labeled with the same terms that we use during our communications. So for example, in our code, the user would book a booking using the BookingService. We could have called it create a booking using the BookingDB class in the code to be more technical, but in that case, we lost our domain based language. And the information that we acquired from the experts is no longer visible in our code.

The Ubiquitous Langauge guarantees that our code is a complete reflection of what our experts have in mind, it also ensures that the developers know exactly how the system components interact with each other in regards to the real world problem. This will make it easier to spot the gaps or the differences between what we have implemented and the real world representation of the model, as well as being able to continuously refine our code to get a more concrete representation of the problem domain.

This language will be under constant refining and improvement. It won’t be a very understandable or clear language to both parties at the beginning. But with constant knowledge crunching and information gathering, it will become much more robust and standard, and it will make future upgrades easier and quicker to understand.

The language used to communicate with the domain experts to gather requirements and information, and the terms during our discussions must be reflected as they are in our code

Bounded Contexts

Bounded contexts are, in their hearts, the application of the Separation of Concerns principle on the domain level. Mainly we would group and collect together relative parts of the overall domain model which represent a single complete context or functionality of the system.

Continuing with our hotel booking app example, here we have two separate functionalities, which are 1)searching for a room 2) and booking a room in a hotel. So you have two separate contexts one of them is the search context and the other is the booking context. Each of them would have its own model representation and domain objects.

Although they may share some concepts, they will have a different representation of those concepts. For example, they both have the concept of a room, but in the context of searching, the room is an item in a list which adheres to the search criteria provided. While for the booking context a room is an item booked for a certain period by a certain client with certain options or added features. The search doesn’t need to represent the client-room relation, but it needs to represent all the room’s features in order to query them. On the other hand, the booking doesn’t need to represent all the room’s features which are necessary for searching, it can just use a room type and night rate to represent it’s room data, but it’s more concerned with the user’s info and the payment method for example.

These subtle distinctions between what a room is in different contexts are really important in defining the context’s boundaries and the relations between different contexts. Those two contexts will need to share some data between each other in order to complete the overall system functionality which is booking a hotel room. This will call for some translations between the two contexts, which we will discuss in the next section.

Context Maps

Bounded context will always need to communicate and/or exchange information, to achieve this we have several patterns which can apply, not all the patterns will be applicable to your situation, so it needs a lot of work and design analysis to choose a pattern.

1. Shared Kernel

2. Customer/Supplier

3. Conformist

4. Anticorruption Layer

5. Separate Ways

6. Open Host Service

7. Published Language


Domain Distillation Techniques

The Core Domain of your system will be mostly hiding within a lot of other domains which are all important for the system to function correctly but are not the main focus of the system. Discovering the core domain requires some distillation techniques and tools to uncover it and possible isolated.

1. Generic Subdomains

Generic Subdomains are the parts of your system which are challenging and required but they are not the core of the domain.

An example would be a calculation algorithm of some sort, that calculates values for reports in a car rental application. This domain, however important it might seem, is not the core domain of the application. It might seem intriguing to invest our best developers in this algorithm but that would risk our core domain being handled by developers who are not the top notch of their game.

We have several solutions to this problem:

  1. Using of The Shelf Software: We might be lucky enough to find a generic solution that is readily available which implements our generic problem, for example, in our reporting domain, we might find a generic reporting app that does that calculation for us. The downsides would be

    a. Integration of that piece of software with our system might not be easy

    b. It might be too generic and contains more power than we need

    c. We might be tied to it without much benefit

  2. Using a Generic/Standardized Domain Model: If our problem already has a standardized or generic domain model which is battle tested in other software and we can reuse that subdomain in our app, then we can apply that to our model and implement it in this way, the downsides are:

    a. We might not be using all of the domain models

    b. The domain model might not match our domain completely and our domain model might lose some of its specific capabilities because of this adaptation

  3. Outsourcing The Subdomain: We might consider outsourcing that part of the app to a third party company to handle it’s development for us, thus relieving our top developers from it and focusing our best assets on the core domain, this also has some downsides like

    a. Coordination between both teams will take sometime

    b. Adaptation of the other team to our domain model might be as adequate as we expect, so we need to have a lot of acceptance tests and automated tests to verify the product

    c. Moving the handling of that subdomain to our development will not be easy because they need to understand a new code written by another team

    d. Code quality of the product will be good or bad depending on the expertise of the outsource team

  4. In-house development: Finally we can resort to developing those parts ourselves, this will make the development tailored specifically for our problem domain and needs, we don’t get any more than we need, integration with our core domain will be smoother as we are the owners of both services, however, this has several disadvantages, mainly:

    a. We will need a team to maintain this service, it will need to be updated and integrated regularly

    b. Some readily available software might have solved the problem

Domain Vision Statement