Domain driven design (DDD) is a software development approach where the structure and language of the code closely mirrors the business domain it models. Use it when your application has complex business logic, multiple teams are working on the same system, or when business rules change frequently and need to stay in sync with the code.
DDD was introduced by Eric Evans in his 2003 book of the same name. The core idea is simple but powerful: the software should speak the same language as the business. If an accountant says ‘invoice’ and the code calls it ‘billingDocument,’ that gap causes bugs, miscommunication, and slow development.
The Core Problem DDD Solves
In most software projects, there is a translation problem. Business stakeholders use one vocabulary; developers use another. Over time, the code becomes a tangle of technical concepts disconnected from what the business actually needs.
DDD addresses this by establishing a Ubiquitous Language – a shared vocabulary used by both developers and domain experts in conversation, in documentation, and in the code itself. When the language is consistent, changes in business rules map directly to code changes without translation.
Key DDD Concepts
| Term | Plain English Meaning | Example (E-commerce) |
| Entity | An object with a unique identity that persists over time | A Customer (identified by CustomerID) |
| Value Object | An object defined by its attributes, not identity | An Address (two identical addresses are interchangeable) |
| Aggregate | A cluster of objects treated as a single unit | Order + OrderItems + ShippingAddress |
| Repository | Abstraction for retrieving and storing aggregates | OrderRepository.findById(orderId) |
| Domain Service | Business logic that does not belong to a single entity | TaxCalculationService, FraudDetectionService |
| Bounded Context | A boundary within which a domain model is consistent | Billing context vs Shipping context |
| Ubiquitous Language | Shared vocabulary used by all team members | Everyone calls it ‘Order’ – not ticket, sale, or transaction |
Bounded Contexts Explained
This is the concept that trips people up the most – and it is also the most important one.
A bounded context is a logical boundary around a part of your domain where a specific model applies. The same word can mean different things in different contexts, and that is okay – as long as you make the boundaries explicit.
Example: In an e-commerce system, ‘Product’ means different things to different teams:
- In the Catalog context: Product has a name, description, photos, and categories
- In the Inventory context: Product has a stock level, warehouse location, and reorder threshold
- In the Pricing context: Product has a price, discount rules, and tax category
DDD says: do not force one Product model to serve all three. Build separate models in separate bounded contexts and define how they communicate at the boundaries.
When to Use DDD – and When Not To
| Good Fit for DDD | Poor Fit for DDD |
| Complex business logic with many rules | Simple CRUD apps (forms that save to a database) |
| Large teams working on the same system | Small projects with 1-2 developers |
| Frequent changes driven by business requirements | Projects where requirements are fixed and clear |
| Need for long-term maintainability | Short-lived or prototype projects |
DDD vs Traditional Layered Architecture
Traditional layered architecture (presentation → business logic → data access) organizes code by technical concern. DDD organizes code by business domain. In a layered architecture, all Order-related code is spread across layers. In DDD, all Order-related code lives together in the Order domain.
The practical result: in a layered system, changing the Order workflow means touching multiple layers across the codebase. In DDD, it usually means changing code within one bounded context. This is why DDD scales much better as complexity grows.
Getting Started: Practical First Steps
- Event Storming: Gather your team and domain experts and map out the business events on a whiteboard. What happens? In what order? Who causes it? This surfaces the domain language naturally.
- Identify your core domain: Not all parts of the system are equally important. The core domain is where your business has a competitive advantage – invest DDD effort there first.
- Start small: Apply DDD patterns to one bounded context before refactoring everything. Pick the most complex area of your system and model it properly.
- Read the Blue Book: Eric Evans’ Domain-Driven Design is still the definitive reference. Vaughn Vernon’s Implementing Domain-Driven Design is more practical and accessible if you want to start coding immediately.
