Domain-Driven Design

Reading Time: 3 minutes

Domain-Driven Design is an Architectural approach with which we can design large systems or say domains where we create a communication channel between the domain experts and the software developers by keeping the structure and language of our code related to Domain.


  • The problem that we have with large domains is that they can be very hard to model.
  • Breaking large domain into smaller and smaller pieces.
  • Determine the boundaries for those smaller pieces.


  • It does give us a set of guidelines and a set of techniques that we can use to try to help us break larger domains into smaller domains.
  • Breaking things down into small pieces gives us a way to determine boundaries.
  • Build a model that the domain experts understand.

How to keep the structure and language of our code related to Domain

Domain in DDD

  • What is Domain in DDD? The business or the idea that we are modeling, The model represents our understanding of the domain.
  • Experts in Domain are people who understand the business and may not understand the software.

Ubiquitous Language in DDD

  • A language that both domain experts and developers can understand and communicate with.
  • Terminology in this language comes from domain experts.
  • For example, if the Domain is Loan then the classes can be LoanApplication, Customer, etc, and methods can be ApplyForLoan, ApproveLoan, etc.

Decomposing the Domain

Large Domain and Sub Domain:

  • Modelling a large domain is mostly very complex and problematic So breaking the large domain to smaller pieces by grouping related ideas, actions, and rules will create Sub Domain.
  • In many instances, concepts in multiple subdomains will look similar but the meaning will change dramatically.

Bounded Context:

Every subdomain has its own ubiquitous language and a model called Bounded Context, So a sub-domain and bounded context is a good candidate for a Micro-service.

Determining a bounded context :

  1. A different area of a domain handled by different groups of people suggests a bounded context.
  2. Change in meaning of the ubiquitous language used means a different bounded context.
  3. Strongly separated bounded contexts will result in smooth workflows. i.e an awkward workflow may signal a misunderstanding of the domain.

Anti-Corruption Layer:

  • Each Bounded context has domain concepts that are unique and not compatible with other bounded contexts.
  • Anti-Corruption Layer is introduced to translate these concepts and prevent Bounded Contexts from leaking into each other so that the Bounded Context can stand alone.

Context Maps:

Context Maps are a way of visualizing Bounded Contexts and the relationships between them.

Domain Building Blocks:

  • Domain Activities: These are the messages in the Reactive System. They form the API for a Bounded Context or a Microservice.
    1. Command: Request to perform an action that could be rejected and causes a change in the domain state.
    2. Events: Represents an action that happened in the past and cannot be changed. It can be broadcast to many destinations within a system.
    3. Queries: a request for information about the domain, Queries should never alter the state of the domain
  • Domain objects :
    1. Value objects: are defined by their own attributes, and are immutable so two value objects are equivalent only if the value of their attributes is the same.
    2. Entity: defined by a unique identity i.e., id or a key, An Entity may change its attributes, but not its identity, So if the identity changes, it is a new entity, regardless of its attributes. It also contains business logic.
    3. Aggregate: An Aggregate is a collection of domain objects bound to a root Entity called the Aggregate Root. Objects in an Aggregate can be treated as a single unit and access to objects in the Aggregate must go through the Aggregate Root. Also, Transactions should not span multiple Aggregate Roots.
  • Domain Abstractions:
    1. Service: Business logic doesn’t always fit with an entity or value object. Such logic can be encapsulated by a Service.
    2. Factories: Sometimes the creation of domain object requires access to File Database, REST API, etc, Factories makes the creation of object abstract usually by having domain interface and multiple implementations.
    3. Repositories: Mostly it operates as an abstraction layer over databases, but they can also work with files, REST APIs, etc. So a repository does not automatically imply a database. A Repository may end up with all of the Create, Read, Update, Delete operations of the object.