DDD Strategic Design
Bounded Contexts, Ubiquitous Language, and Subdomains.
Strategic Domain-Driven Design
Tactical DDD covers code patterns (Entities, Value Objects), but Strategic DDD is about high-level architecture. It answers the question: "How do we split this massive business problem into manageable software pieces?"
The Core Pillars
Ubiquitous Language
A shared vocabulary between developers and domain experts. If the business calls it a 'Booking', the code shouldn't call it a 'Reservation'.
Bounded Contexts
Explicit boundaries within which a specific model applies. 'User' in the Sales Context is different from 'User' in the Support Context.
Subdomains
classifying parts of the system into Core (Money maker), Supporting (Necessary), or Generic (Buy it off the shelf).
Bounded Contexts
A large system cannot have a single unified data model. It becomes a bloated monolith.
Instead, we define Contexts.
- Sales Context: Needs
Customer(Lead status, Pipeline stage). - Shipping Context: Needs
Customer(Address, Shipping preferences).
Don't try to make one giant Customer class. Do create two distinct models that share an ID.
Personal Note
Identifying boundaries is harder than writing the code. A good heuristic: If the definition of a term changes (e.g., a "Ticket" means a sale in Marketing but a bug in Support), you've crossed a boundary.
Practical Domain Modeling: E-Commerce Platform
Context Mapping Example
Sales Context Domain Model
Customer = Potential Revenue
- Contains lead status (NEW, CONTACTED, QUALIFIED, CONVERTED)
- Tracks lead source (WEBSITE, REFERRAL, COLD_CALL)
- Manages pipeline stage progression
- Can convert to Opportunity when qualified
- Business rules prevent skipping pipeline stages
Opportunity Entity
- Has budget and stage (DISCOVERY, QUALIFICATION, PROPOSAL, etc.)
- Calculates win probability based on stage
- Links back to original customer/lead
Order Context Domain Model
Customer = Someone Who Buys
- Contains billing address and payment methods
- Tracks order history
- Validates payment method sufficiency
- Different business rules than Sales context
Order Entity
- Contains items and shipping address
- Validates order requirements
- Calculates totals
- Manages status transitions (PENDING → PAID → SHIPPED)
Shipping Context Domain Model
Customer = Delivery Destination
- Contains multiple delivery addresses
- Manages shipping preferences
- Has business rules for shipping restrictions
- Tracks delivery time estimates
Shipment Entity
- Links to order and customer
- Contains items to ship
- Estimates delivery dates based on zones
- Supports expedited shipping where available
Context Integration: Anti-Corruption Layer
Purpose: Prevents domain model pollution between contexts
- Translates Sales context lead to Order context customer
- Shares only ID, not entire object graphs
- Maintains context boundaries
- Handles data model differences
Key Principle: Each context owns its domain model completely. Integration happens through translation, not shared objects.
Context Mapping
How do these contexts talk to each other?
- Partnership: Two teams succeed or fail together. High coordination.
- Shared Kernel: Sharing a small, common library (e.g., Auth definitions). Dangerous if it grows too big.
- Customer-Supplier: Upstream team feeds downstream. Downstream is dependent.
- Conformist: Downstream has no say; they must accept the Upstream model as is.
- Anti-Corruption Layer (ACL): The most useful pattern. A translation layer that prevents an external messy model from polluting your clean internal model.
Subdomain Types
Where should you spend your innovation tokens?
| Type | Description | Strategy |
|---|---|---|
| Core | The unique value prop. Why the business exists. | Build it yourself. Put best devs here. |
| Supporting | Necessary, but not the differentiator. | Outsource or use junior devs. |
| Generic | Solved problems (Auth, Billing, Email). | Buy SaaS. Don't build your own Stripe. |