What Is a Domain? Key Concepts of Domain‑Driven Design Explained
This article explains the definition of a domain in Domain‑Driven Design, its relationship with contexts, challenges of persisting aggregates, the debate over rich versus anemic models, and practical guidelines for clear layering and handling many‑to‑many relationships in backend systems.
What is a Domain?
In Domain‑Driven Design (DDD), a "domain" refers to the collection of business‑related knowledge; essentially, it is the business itself, such as tax processing, accounting, or sales records.
Definition
Domain (Domain) is a collection of business‑related knowledge.
In plain terms, a domain is business knowledge. Different business areas (finance, CRM, OA, e‑commerce) have distinct rules, and the computer merely automates those rules. The elements that constitute a domain are specific business scenarios.
By dividing business scenarios, we obtain sub‑domains:
Core domain: scenarios critical to the business, e.g., posting questions, viewing threads, replying in a community app.
Supporting domain: scenarios that support important business functions, such as login or password recovery.
Generic domain: scenarios that have become relatively independent support functions, like real‑name verification or CAPTCHA.
What is the relationship between Domain and Context?
If a domain is composed of scenarios, a context is composed of models; therefore, there is no containment relationship between them, nor a one‑to‑many mapping.
Contexts support domains, and domains derive contexts. DDD modeling bridges business problems (domains) and solutions (models), analogous to the mathematical relation f(x) where f is the modeling process.
For example, an e‑commerce site has multiple sales channels (retail, wholesale, corporate). Those are the domains; developers design models such as Order and Product to support them.
How should an Aggregate be persisted?
An aggregate has two responsibilities: ensuring business consistency and storing data as a whole. Persistence is a classic difficulty.
For consistency, Eric Evans suggests loading the whole aggregate, modifying it in memory, and persisting it back, preventing inconsistent state.
However, memory is limited and data must survive power loss, so it must be read from disk, which is slow. Relational databases store data as collections with relationships, requiring ORM conversion between object and relational models, which complicates aggregate persistence and can degrade performance.
Why does the Rich Model not fit typical programming habits?
The rich (or “active”) model puts business behavior inside the model. While this aligns with object‑oriented ideas, in practice it can feel awkward; some developers even forget how to write code after learning DDD.
Extreme cases involve calling a repository from an aggregate root to persist itself, which clashes with JPA’s need for type information.
From a philosophical viewpoint, an action consists of subject + verb + object. In programming, the subject is the entity, the verb is the method, and the object is the data it manipulates. A suitable rich model gives “blood” (behavior) to the subject while keeping the object “anemic”.
How to achieve clear layering?
Two principles for layering:
Layering must have a clear purpose; purposeless layers cause extra problems.
Layers must consider the frameworks and libraries used, otherwise you get a “layer‑cake” architecture.
The goal of layering is to isolate differences. When differences appear, each layer’s responsibility changes:
Presentation layer: handles inbound protocols; its objects are data packets, not domain concepts.
Application layer: handles use‑cases such as user registration; its objects are use‑case DTOs.
Domain layer: provides generic domain capabilities like creating a user; its objects are domain models.
Technical infrastructure layer: offers technical implementations (e.g., JPA) without knowing domain details; it works with generic objects supplied by the domain layer.
How are many‑to‑many relationships usually handled?
Many‑to‑many relationships blur the definition of the object, leading to confusion. For example, an order has many products, but the proper model is Order → OrderItem ← Product. Similarly, a user can collaborate on many documents, which is modeled via a DocumentParticipant entity.
Clarifying the intermediate entity makes code clearer, simpler, and decoupled. In real life, a shareholder entity mediates the many‑to‑many relationship between a company and its owners.
Reference
“DDD Concept Reference”.
DevOps
Share premium content and events on trends, applications, and practices in development efficiency, AI and related technologies. The IDCF International DevOps Coach Federation trains end‑to‑end development‑efficiency talent, linking high‑performance organizations and individuals to achieve excellence.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.