Domain-Driven Design is a concept introduced by Eric Evans in his book Domain-Driven Design: Tackling Complexity in Heart of Software. It is an architectural approach to designing large systems. It suggests designing software architecture by looking at it in a top-to-bottom fashion.
What is Domain?
The domain is the heart of the software around which the application revolves. The dictionary meaning of domain is “Sphere of Knowledge“. However, in the context of software development, it refers to the business idea that software is attempting to model. The domain is the area of knowledge around which application revolves. Domain provides a set of guidelines that define the interaction of business objects with each other to process modelled data.
The goal of domain-driven design is to model software that domain experts can understand. It builds a communication channel between domain experts and software developers. Domain experts are the people having concrete knowledge of the business area that software targets. For example, a bank manager would be a domain expert for a banking system.
Terminology related to Domain-Driven Design
In order to strategically design software, the domain-driven design brings the following terms in scope:
As already mentioned, the domain is the knowledge or data around the problem that the software attempts to solve. On the other hand, the model refers to the prospective solution to that problem. It also provides the core logic that the application implements. In a nutshell, the model helps in solving business problems.
As already mentioned, DDD helps to build a communication channel between software developers and domain experts. Ubiquitous Language facilitates that communication. Thus, Ubiquitous language is a common language acting as a means of communication between developers and domain experts. For example, nouns and common verbs related to domain are used to name classes and methods respectively.
Bounded context is a description of a boundary in which the domain model is defined. It also acts as a threshold within which a particular domain model is applicable and valid.
Model a Software using Domain-Driven Design
While modelling a domain-driven software, the following conceptual tools are useful:
An entity is a class having properties associated with it. The instances of an entity class possess a global identity. This identity remains unchanged during the entire life span. However, there can be changes in the state of some or all the properties (except identity). Thus an entity can be uniquely identified using an ID. In a programming context, it persists as a row in DB where identity may be a primary key.
Value objects are immutable objects so they do not change in their lifespan. They also lack an identity associated with them.
For Example: Consider a user object as shown below:
Here, the User class is an entity while the address is a property of the user. It may change if the user wishes to update his/her address. UserId is the identity and remains unchanged for the user.
Service in domain-driven design is a class between entities and value objects. It contains domain logic that may not exist in entity or value object(s).
Aggregate & Aggregate Root
An aggregate is a cluster of domain objects treated as a single unit. For example, order and its line items. These will be separate objects but it’s useful to treat the order (together with its line items) as a single aggregate.
One of the components in aggregate objects is the aggregate root. Any references from outside the aggregate should only go to the aggregate root. The root thus ensures the integrity of the aggregate as a whole.
Factory & Repository
Factory and repository are the ways of managing an aggregate. The factory is responsible for beginning the lifecycle of an aggregate. The repository is responsible to manage the other lifecycle events of an aggregate. In technical terms, the factory creates an aggregate while the repository performs read, update, and delete operations. Factory and repository together implement CRUD operations.
Also note that sometimes, a single class may combine all the CRUD operations. In such a case, the repository becomes responsible for beginning the lifecycle of the aggregate.
Domain-Driven Design is to simplify the software architecture by breaking it into smaller pieces. Reactive architecture is also about having a set of services having clear boundaries between them. Hence, the guidelines set by DDD are in line with those of the reactive systems. So, both are quite compatible and hence often used together.
Do check out the blog post on Reactive System: A Better Architecture for Modern Software. It explains about reactive architecture, its principles and how a reactive system meets users’ expectations.