Domain-Driven Design Vocabulary: 30 DDD Terms Explained

Bounded context, aggregate, entity, value object, domain event, and tactical DDD vocabulary for software architects.

Domain-Driven Design — often shortened to DDD — is an approach to software development that puts the business domain at the centre of every technical decision. Coined by Eric Evans in his 2003 book Domain-Driven Design: Tackling Complexity in the Heart of Software, it has become a standard reference point for architects and senior developers working on complex systems. The vocabulary is precise and deliberate: each term names a concept that helps teams model reality more accurately in code. If you work with microservices, event-driven systems, or any moderately complex backend, you will encounter this language in design meetings, architecture reviews, and code reviews. This guide covers the essential DDD terms — what they mean, and how real developers use them in conversation.


Core Strategic Terms

Strategic DDD is about understanding the business landscape before writing a single line of code. These terms help teams carve the system into meaningful parts.

Domain — the sphere of knowledge and activity around which the application logic revolves. In practical terms, it is the problem space your software is trying to solve. A logistics company’s domain is freight movement; a bank’s domain is financial transactions.

“We need to understand the domain before we start modelling. Let’s spend a day with the operations team."
"That validation rule lives in the domain layer, not the application layer.”

Subdomain — a distinct part of the overall domain. DDD recognises three types:

  • Core subdomain — the competitive differentiator; the part where the company gains unique advantage. This is where you invest the most engineering effort.
  • Supporting subdomain — necessary but not differentiating; often built in-house but with less investment.
  • Generic subdomain — solved problems that many companies face; typically handled by off-the-shelf solutions (email delivery, payment processing, authentication).

“Pricing is our core subdomain — we build it ourselves with a full DDD model. Billing is generic; we just use Stripe."
"Don’t over-engineer the reporting module. It’s a supporting subdomain.”

Bounded Context — a clearly defined boundary within which a particular model is consistent and valid. Inside a bounded context, every term has one precise meaning. The same word may mean something different in a neighbouring bounded context. This is one of the most important concepts in all of DDD.

“The word ‘customer’ means different things in the Sales context and the Shipping context. We need to keep those models separate."
"Before we add this field, let’s check which bounded context owns that concept.”

Ubiquitous Language — a shared vocabulary developed collaboratively by developers and domain experts, used consistently in code, documentation, and conversation. The goal is to eliminate translation between what the business says and what the code does.

“Let’s update the ubiquitous language glossary — the business now calls it an ‘engagement’, not a ‘contract’."
"If the domain expert says ‘shipment’ and the code says ‘delivery’, we have a language problem.”

Context Map — a diagram or document that shows the relationships between bounded contexts: how data flows between them, who is upstream, who is downstream, and what integration patterns are used.

“Can you update the context map? We added a new bounded context for notifications."
"The context map shows that Orders is upstream of Fulfilment — that’s why the change broke things.”


Tactical Building Blocks

Tactical DDD gives you a vocabulary for the objects inside a bounded context. These patterns are about how to model a domain in code.

Entity — an object that has a distinct identity that persists over time, even as its attributes change. A User with an ID is an entity; even if the user changes their email address, they are still the same user.

“User is definitely an entity — it has an ID and its state changes over its lifecycle."
"Don’t compare entities by value. Compare them by identity.”

Value Object — an object that is defined entirely by its attributes and has no conceptual identity of its own. Two value objects with the same data are interchangeable. Common examples: a money amount, a postal address, a colour code.

“Money should be a value object — immutable, compared by value, with currency and amount."
"Address has no ID because it’s a value object. If the address changes, we replace it.”

Aggregate — a cluster of entities and value objects treated as a single unit for data changes. Every aggregate has a boundary and enforces its own internal consistency rules. You persist and retrieve an aggregate as a whole.

“The Order aggregate includes the order header and all its line items."
"If you need to change a line item, you go through the Order aggregate — never directly.”

Aggregate Root — the single entity at the top of an aggregate that controls all access to the objects inside it. External code can only hold a reference to the aggregate root, not to internal entities.

“OrderItem is inside the Order aggregate. You can’t fetch an OrderItem directly — you load the Order and navigate from the root."
"All business rules for this aggregate are enforced by the aggregate root.”

Domain Event — something that happened in the domain that other parts of the system might need to know about. Domain events are named in the past tense and represent facts: OrderPlaced, PaymentFailed, UserRegistered.

“When a payment succeeds, we publish a PaymentProcessed domain event. The fulfilment service listens for that."
"Domain events are immutable — they are facts, not commands.”


Services and Infrastructure Patterns

These terms describe how behaviour and data access are organised when they do not fit neatly inside an entity or value object.

Domain Service — a stateless service that contains domain logic which does not naturally belong to any single entity or value object. A typical example is a pricing calculator that involves multiple aggregates.

“The currency conversion logic doesn’t belong to any single entity, so we put it in a domain service."
"If you find yourself adding behaviour to an entity that feels forced, it might belong in a domain service.”

Application Service — a thin layer that orchestrates domain objects to fulfil a use case. Application services handle transactions, authorise requests, and coordinate between domain services and repositories. They contain no domain logic themselves.

“The application service calls the repository to load the aggregate, invokes the domain method, then saves it back. That’s all it does."
"Don’t put business rules in the application service. That logic belongs in the domain.”

Repository Pattern — an abstraction that provides collection-like access to aggregates, hiding the details of how data is persisted and retrieved. The domain code talks to a repository interface; the infrastructure layer provides the implementation.

“The OrderRepository interface is in the domain layer. The Postgres implementation is in the infrastructure layer."
"We’re swapping the data store. Because we used the repository pattern, the domain code is untouched.”

Anti-Corruption Layer — a translation layer that sits between two bounded contexts (or between your system and a legacy system) to prevent one model’s assumptions from bleeding into another. It maps incoming data into your own model’s language.

“We built an anti-corruption layer between our new Orders context and the legacy ERP. We translate their concept of a ‘job’ into our ‘order’."
"Without an anti-corruption layer, every change in the upstream service breaks our model.”


Collaborative Discovery

Event Storming — a collaborative workshop technique in which domain experts and developers use sticky notes to map out domain events, commands, aggregates, and policies across a business process. It is one of the fastest ways to develop a shared understanding of a complex domain.

“Before we start modelling, let’s run an event storming session with the product team."
"Event storming helped us discover three bounded contexts we hadn’t even considered.”


How to Use These Terms in Conversation

Understanding a term is one thing; using it naturally in a technical discussion is another. Here are realistic scenarios where DDD vocabulary appears.

Architecture review: “We’re splitting the monolith into bounded contexts. The core subdomain — dynamic pricing — gets a rich domain model with aggregates and domain events. The notification service is a generic subdomain; we’ll keep it simple.”

Code review: “This method on the User entity is querying the Order aggregate directly. That breaks aggregate boundaries. The application service should load each aggregate separately and coordinate them.”

Design discussion: “We need an anti-corruption layer here. The payment provider uses ‘transaction’ in a way that conflicts with our own Transaction value object. Let’s translate at the boundary before it pollutes our model.”

Incident debrief: “The issue was that two services both modified the Shipment aggregate without going through the aggregate root. We lost consistency. Going forward, all writes must go through the root and publish a domain event.”


Quick Reference Table

TermTypeOne-line definition
Bounded ContextStrategicBoundary within which a model is consistent and unambiguous
Ubiquitous LanguageStrategicShared vocabulary used by developers and domain experts alike
AggregateTacticalCluster of objects treated as one unit; persisted together
Aggregate RootTacticalThe single entry point to an aggregate; enforces invariants
EntityTacticalObject with a persistent identity that changes over time
Value ObjectTacticalImmutable object defined entirely by its attributes
Domain EventTacticalAn immutable record of something that happened in the domain
Domain ServiceTacticalStateless service for domain logic that spans multiple objects
Repository PatternInfrastructureAbstraction for loading and saving aggregates
Anti-Corruption LayerIntegrationTranslation layer preventing model contamination at boundaries

Mastering DDD vocabulary will not automatically make your architecture better — but it will give you and your team the precise language needed to have the right conversations. When everyone in the room uses the same terms with the same meanings, design decisions become faster, cleaner, and easier to communicate. Start by identifying your own system’s bounded contexts and core subdomain, then build the ubiquitous language from there.