Engineering Playbook
Enterprise Architecture

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?

  1. Partnership: Two teams succeed or fail together. High coordination.
  2. Shared Kernel: Sharing a small, common library (e.g., Auth definitions). Dangerous if it grows too big.
  3. Customer-Supplier: Upstream team feeds downstream. Downstream is dependent.
  4. Conformist: Downstream has no say; they must accept the Upstream model as is.
  5. 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?

TypeDescriptionStrategy
CoreThe unique value prop. Why the business exists.Build it yourself. Put best devs here.
SupportingNecessary, but not the differentiator.Outsource or use junior devs.
GenericSolved problems (Auth, Billing, Email).Buy SaaS. Don't build your own Stripe.