Skip to content

Domain-Driven Design

Domain-Driven Design

Domain-Driven Design: Tackling Complexity in the Heart of Software by Eric Evans is one of the most influential books in modern software architecture. First published in 2003, it introduced the concepts that became known as Domain-Driven Design (DDD) and significantly shaped how large, complex business systems are designed.


The book focuses on how to handle complex business logic in large systems.

Evans introduces several concepts that work together.

One of the most important ideas in the book.

Developers, business analysts, product owners, and domain experts should use the same language when discussing the system.

Bad Example

Business says:

“Customer Subscription”

Developers call it:

“Contract”

Database calls it:

“CustomerAgreement”

The team is now using three different concepts for the same thing.

DDD Approach

Everyone uses:

“Subscription”

Everywhere:

  • Meetings
  • Documentation
  • Code
  • Database naming
  • APIs

Example:

public class Subscription
{
public SubscriptionStatus Status { get; private set; }
}

The code reflects the business language.

This reduces misunderstandings significantly.

DDD distinguishes between:

Core Domain

The part that provides competitive advantage.

Example:

For Spotify:

  • Recommendation algorithms
  • Music discovery

For Amazon:

  • Product recommendation
  • Fulfilment optimisation

For a bank:

  • Risk modelling
  • Loan approval logic

These areas deserve the strongest engineering effort.

Supporting Domains

Important but not differentiating.

Examples:

  • Reporting
  • Notifications
  • Billing integrations

Generic Domains

Can often be purchased or reused.

Examples:

  • Authentication
  • Logging
  • Email systems

The key lesson:

Put your best people on the Core Domain.

Evans strongly criticises “database-centric” designs where entities are just containers of data.

Anemic Model

public class Order
{
public decimal TotalAmount { get; set; }
}

All behaviour lives elsewhere.

Rich Domain Model

public class Order
{
public void ApplyDiscount(Discount discount)
{
// Business rules here
}
public void Confirm()
{
// Business rules here
}
}

Business rules stay close to the data they govern.

A large portion of the book deals with organising large systems.

Evans noticed that large organisations often have different teams using the same words with different meanings.

Example:

Sales Context

Customer = company buying products

Support Context

Customer = individual user opening tickets

Both are correct.

Trying to force one model causes confusion.

One of the most important DDD concepts and arguably the foundation of modern microservices.

A Bounded Context is a boundary within which a model has a specific meaning.

Example:

Ordering Context

Order
Customer
Product

Billing Context

Invoice
Account
Payment

Each context owns its language and rules.

This prevents a gigantic, tangled enterprise model.

Many modern microservice architectures are effectively implementations of Bounded Contexts.

Aggregates help maintain consistency.

Example:

Order
├─ Order Line
├─ Order Line
└─ Order Line

The Order acts as the Aggregate Root.

All modifications happen through it.

order.AddItem(product);
order.RemoveItem(product);

Instead of directly manipulating children.

This helps enforce business invariants.

Entity

Has identity.

Customer

Even if properties change, it is still the same customer.

CustomerId = 123

Identity matters.

Value Object

Defined only by its values.

Money
Address
DateRange

Example:

new Money(100, "EUR")

Two identical Money objects are interchangeable.

DDD encourages heavy use of Value Objects.

Repositories provide access to aggregates while hiding persistence details.

IOrderRepository

Instead of:

DbContext

being used everywhere.

The domain remains independent of storage concerns.

A concept that later became foundational in event-driven architectures.

Example:

OrderPlaced
PaymentReceived
InvoiceGenerated

Business events represent meaningful things that happened.

OrderPlacedEvent

Other parts of the system can react to those events.


The central message is:

Software should be designed around the business domain and built through close collaboration between domain experts and developers.

Many software projects fail because developers focus on technical concerns (databases, frameworks, APIs, infrastructure) while losing sight of the actual business problems they’re trying to solve.

Evans argues that:

  • The business domain should drive the software design.
  • Developers and domain experts should develop a shared understanding of the problem.
  • The software model should reflect that understanding.
  • Complexity should be managed by carefully structuring the domain and its boundaries.

The main three ideas:

  1. Complex software should be organised around business concepts, not technical layers.
  2. Developers and domain experts must share a common language and model.
  3. Large systems should be divided into bounded contexts with clear ownership and responsibilities.

The focus should be especially on:

  • Ubiquitous Language
  • Bounded Contexts
  • Aggregates
  • Domain Events
  • Strategic Design

These five concepts deliver the majority of the long-term value from DDD and appear repeatedly in modern enterprise and microservice architectures.

In summary:

DDD is about turning business knowledge into software models that accurately represent the real-world problem being solved.


Many architecture books focus on technology.

Evans focuses on:

Understanding business complexity.

And that is usually the hardest part.

Many current practices originated directly or indirectly from DDD:

  • Microservices
  • Event-driven architecture
  • CQRS
  • Event Sourcing
  • Strategic design
  • Context mapping
  • Domain events

Even teams that have never read Evans often use concepts introduced in the book.

3. It Helps Large Systems Stay Maintainable

Section titled “3. It Helps Large Systems Stay Maintainable”

Without DDD, large systems often become:

Big Ball of Mud

Characteristics:

  • Thousands of classes
  • Inconsistent naming
  • Duplicate business rules
  • Tight coupling
  • Difficult maintenance

DDD provides tools to structure complexity.

One of the strongest benefits.

When business rules change:

Business Model
↓
Domain Model
↓
Code

Changes are easier because the software already mirrors business concepts.

Many developers think DDD is mostly about:

  • Aggregates
  • Entities
  • Repositories

Evans would probably say the most important part is:

Continuous collaboration between developers and domain experts.

The modelling conversations are often more valuable than the resulting code.