Introduction to Domain Driven Design
Domain Driven Design (DDD) is an approach to developing software for complex needs by deeply connecting the implementation to an evolving model of the core business concepts.
DDD is suitable if it is required to build a software that has complexity in its business process (business domain). So, not every software is suitable for DDD, for example CRUD applications are not suitable as they are not very complex.
Teamwork is very important within DDD since you need to keep in touch with the users/clients (Domain Experts). Moreover, you build the software for them, not for you. Just like someone said:
“the software can fail either in two ways, you build the things wrong or you build the wrong things.”
In that case, you have to ensure that you understand the business that you’re going to build. This is what DDD is all about.
To summarize, DDD can be described as a technique for developing software that focuses on collaboration between technical experts and domain experts. Therefore, we must keep focus with the domain experts instead of the nitty-gritty details of the technical stuff.
Steps to get started with DDD
The first and big step in DDD is to keep in touch with the business/domain expert. while having discussion with the domain expert below points have to be taken care,
- Learning about the problem domain, i.e. the specific problem the software you’re working on is trying to solve. Look at the big picture of the current business process.
- Breaking the domain into sub-domains.
- Focusing on one sub-domain at a time with the domain expert, and always use ubiquitous language to define working out terminology.
- Creating a bounded context between sub-domain. Again, ubiquitous language should always be used throughout the bounded context, from conversations to code, in the diagram, on the whiteboard, in the design document, team discussion, etc. The point is to use the bounded context everywhere.
- Ideally, there will be a different team, codebase and database for each bounded context.
- Since everyone is working for their bounded context, so they are free to change anything within their context.
- For all cross-cutting concerns those are shared between bounded context (we call it shared kernel), any changes should be known and agreed between all team in every bounded context.
- Always stay focused on the domain’s behaviors rather than domain’s state (favor a rich model over an anemic model (Anemic domain model is the use of a software domain model where the domain objects contain little or no business logic) ).
Always use ubiquitous language (i.e. same terminology) across the team, break the domain into smaller sub-domains and give an isolation (i.e. bounded context) by defining the boundary and think about how the sub-domain within the bounded context can communicate to each other using interfaces/ crafted software contract.
What Should Be Avoided in DDD
In DDD implementation, need to be careful of certain practices those are too common among software developers. They are,
Using a Data-Centric View When Modeling the Problem Domain
Usually, the data model is the first thing that an architect/developer would start to design. They always consider that data is the most important thing because data is all that we need to report. If you start with DDD, you must change this mindset. Data on its own is meaningless. Only logic gives data a meaning, and the same data can have a different meaning in different contexts. Therefore, we must start with context and logic instead of data.
Focusing on Implementation Details Like Entities, Value Objects, Services, Factories, and Repositories Instead of the Core Concepts
Entities, value objects, repositories, and so forth don’t have a meaning until we defined the ubiquitous language, bounded contexts, and the interfaces/crafted software contract. If we start to early with the implementation details like entities, then it’s a good chance that the result would be an anemic domain surrounded by a lot of services and business logic scattered everywhere.
Using Generic and Developer-Specific Terms and Concepts When Implementing the Application
We should never use concepts like save, update, delete, handle, manage, etc. Those concepts are too technical- abstract concepts with no specific meaning. Instead, we must stay focused on the business concepts. Those concepts (i.e. save, update, etc) are not related to business concepts. To understand this, always imagine the client running his business without computers (doing specific tasks manually). So, always think from the business/domain expert perspective, and give a clear context on it. Avoid generic terms that can lead to different meanings in different, non-specific contexts.
Overrating DB Transactions Instead of Focusing on the Business Processes or Transactions
Within DDD, business transactions are more important than DB transactions. DB transactions are ACID(Atomicity, Consistency, Isolation, Durability), strongly consistent, and short running, while business transactions are not. In fact, in the real life, we do not know about DB transactions, we just know about business transactions. For example, imagine when you are sitting in a restaurant and order some foods or beverages. Within the order transaction, realize it or not, there will be a process with some asynchronous tasks with many possible inconsistent state changes; by the end, all states will be consistent (eventually consistent). This black box process works, is scalable, and is widely acceptable to everyone. Therefore, with DDD, do not ever think about DB transactions. Instead, always think about the real world processes, such as actions (behaviors) and their possible outcomes, or how to compensate for the actions if failures occurs.
For understanding more about DDD, refer Domain-Driven Design: Tackling Complexity in the Heart of Software by Eric Evans
DDD building blocks topic will be described in the next article....