Domain Driven Design
Domain Driven Design, is an approach to designing a software system by getting direct inputs from the domain experts and modeling the software accordingly. These domain experts can be the product owners or someone who is close to the product and understands the need of the market/end-users. DDD helps to make the software design more modular which results in a simple codebase & maintainability. This approach is particularly suited for complex domain applications with multiple complex business logic.
This is very well answered by Eric Evans, the founder of DDD.
Every software program relates to some activity or interest of its user. The heart of software is its ability to solve domain-related problems for its user. All other features, vital though they may be, support this basic purpose. When the domain is complex, this is a difficult task, calling for the concentrated effort of talented and skilled people.Developers have to steep themselves in the domain to build up knowledge of the business.
To simplify this further, lets dive into some of the important concepts of DDD.
DDD helps to fill the gap between developers & domain experts by using a common language. This might sound like not a big deal, but actually, it is. For eg: In the travel & tourism application, let's say that the engineering team named an entity a
Trip but the domain experts call it an
Itinerary. This brings conflict and understanding issues across the team and that is why there should be a common language used. This also means that the engineering team should name their classes, packages, table/document names in sync with what the product team refers to.
It's a good sign when the engineering team starts asking a lot of "Why" questions, this shows an interest within the team to learn more about the domain. Ubiquitous language could be your first step to transforming the engineering team to become domain experts.
A domain will always have logical separations, also called subdomains. Sometimes it becomes very difficult to manage the codebase across these subdomains. There will be entities that will make sense in one domain but is irrelevant in another. This is the sign of explicit separation from each other and that is where Bounded contexts come to the rescue. Bounded contexts will define boundaries in a domain.
A good example, in this case, is again in travel & tourism application. An entity
Itinerary can become a shared resource as it will be used by other subdomains. Instead of creating an
Itinerary as a generic entity with a mixture of all related attributes, you create domain boundaries and create different
Itinerary for different subdomains.
For eg: Sales & Reservations can be two different subdomains and both will have their own
Irrespective of DDD, I strongly suggest every project should apply Bounded contexts. In every project, there will be always this one stakeholder who will try to increase the scope of the domain. Bounded context helps not only to manage complexity but also to deliver results in the first place.
One of the major concepts of the DDD approach is to address the business logic, not all, but the most essential part of it, and that's your "Core domain". In the travel & tourism application, not every business logic is essential, for eg: sending booking email alerts to the hotel can be easily done by using any third-party application, email sending is not the business logic you want to solve. In this case, the core domain could be booking management, rooms availability, price checking, etc.
In every software, everything boils down to how we model our entities. An entity is not defined by its attribute but by its identity.
A value object is just another object but without identity. They are defined by their attributes and it also helps to avoid primitive obsession. With Value Objects, it doesn't matter with "Who" they are, instead, it matters with "What" they are. For example, a
Duration can be a value object which can be part of
Duration can be composed with
endDate, it will have its own validation such as
endDate cannot be before
startDate and it will be immutable.
Currency is another example of a value object.
The other important notions such as the Layered Architecture, Repositories, Domain Events, Aggregates, etc, comprise the tactics of how you should build your software project.
Should I use DDD in my current/next project?
DDD is not applicable to all types of projects, it has its own limitations. Don't apply DDD everywhere by considering it as a silver bullet. Amount of data, Performance, Business logic complexity, Technical complexity, etc, are a few project attributes on which the approach can be decided. DDD fits well in the cases where the project has a lot of complex business rules. It won't help you if you work with big data, need to achieve outstanding performance or program against hardware systems.
DDD is only responsible to tackle business logic complexity. So for eg, in the case of Twitter, DDD won't help much as the real challenges in this kind of application are performance & scalability. The business logic itself is pretty simple in Twitter. A good example of DDD can be real-world ERP systems. ERP systems tend to be slower due to complex business rules are getting applied to a moderate amount of data and the major focus of these systems is to deal with business complexity. The biggest challenge in such projects is to handle business logic complexity in such a way that it would be possible to extend and maintain the solution in the long run. That is exactly the task that domain driven design practices are aimed to solve. They help us create codebase, that is simple & maintainable, which helps to extend the business logic in the longer run.
With DDD, it's not about just writing the code, it's more about the practices. To get the most out of domain driven design, you should constantly refine your domain knowledge with the help of the experts in your company, and it shouldn't be a one-way process, constant two-way communication between engineering & domain experts is very important. Another important implication of domain-driven design is that you should always strive to become a domain expert yourself. Constantly work with the experts and strive to help them simplify or even completely rethink the problem. Your code, if built using the ubiquitous language, can become a great help for yourself. Developers are often enthusiastic about coding due to some technical challenges and sometimes this can become an issue due to lack of communication which should be completely avoided. To benefit them the domain-driven design techniques the most, you should always try to dive into the domain you are working in as much as possible. It might be boring at the start because the domain knowledge you get working on one project can hardly be applied to another, but in reality, it is not the case. When you write the code, you start writing in the same language(Ubiquitous Language) that is used by the domain experts, you will start looking at the project from the domain expert's perspective. Along with this, you will also learn the concepts of DDD and that will help you to apply them in other projects.
Again, DDD is not something that can be covered in a blog post, it's a huge topic and might take weeks to understand and years of experience to master it. There are various resources available online that can help you to understand much better.