Skip to main content

Strategic Decisions: A Framework for DDD Choices

Strategic DDD decisions shape your system's architecture for years. This chapter provides frameworks for making these decisions systematically, not ad-hoc.

TL;DR​

DecisionKey QuestionFramework
Context boundariesWhere to draw lines?Linguistic + team + change analysis
Integration patternHow contexts communicate?Control + model quality matrix
Subdomain investmentWhere to focus?Core/Supporting/Generic classification
Technology choicesWhat to use?Fitness function evaluation

The Strategic Decision Framework​

Decision 1: Bounded Context Boundaries​

The Analysis Framework​

Score each potential boundary on these dimensions:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ BOUNDARY ANALYSIS SCORECARD β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ β”‚
β”‚ LINGUISTIC COHESION (1-5) β”‚
β”‚ Do terms have consistent meaning within boundary? β”‚
β”‚ 5 = Perfect consistency β”‚
β”‚ 1 = Same words mean different things β”‚
β”‚ β”‚
β”‚ TEAM ALIGNMENT (1-5) β”‚
β”‚ Can one team own this boundary? β”‚
β”‚ 5 = Natural team ownership β”‚
β”‚ 1 = Multiple teams, unclear ownership β”‚
β”‚ β”‚
β”‚ CHANGE COUPLING (1-5) β”‚
β”‚ Do things inside change together? β”‚
β”‚ 5 = Changes are isolated within β”‚
β”‚ 1 = Changes ripple across boundaries β”‚
β”‚ β”‚
β”‚ DATA COHESION (1-5) β”‚
β”‚ Is data naturally grouped? β”‚
β”‚ 5 = Clear data ownership β”‚
β”‚ 1 = Data needed from many places β”‚
β”‚ β”‚
β”‚ CONSISTENCY REQUIREMENTS (1-5) β”‚
β”‚ Does this need strong consistency internally? β”‚
β”‚ 5 = Strong consistency needed β”‚
β”‚ 1 = Eventual consistency acceptable β”‚
β”‚ β”‚
β”‚ TOTAL: ___/25 β”‚
β”‚ >20 = Strong boundary β”‚
β”‚ 15-20 = Reasonable boundary β”‚
β”‚ <15 = Reconsider boundary β”‚
β”‚ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Example: E-Commerce Boundary Analysis​

Candidate: Orders Context

DimensionScoreReasoning
Linguistic5"Order", "Line Item", "Checkout" are clear
Team4Orders team owns it, some overlap with Payments
Change4Order logic changes independently
Data4Order data is self-contained
Consistency5Order must be consistent
Total22/25Strong boundary

Candidate: "Customer" Context

DimensionScoreReasoning
Linguistic2"Customer" means different things everywhere
Team2Multiple teams need customer data
Change2Customer changes affect many areas
Data2Customer data spread across systems
Consistency3Some consistency needed
Total11/25Weak boundary - split it

Decision: Split "Customer" into Multiple Contexts​

Decision 2: Integration Patterns​

The Control-Quality Matrix​

Choose integration pattern based on:

  1. Control: Do you control the upstream system?
  2. Model Quality: Is the upstream model good?
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ β”‚
β”‚ MODEL QUALITY β”‚
β”‚ Low High β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ You β”‚ β”‚ β”‚ β”‚
β”‚ Control β”‚ ACL β”‚ Customer- β”‚ β”‚
β”‚ β”‚ β”‚ Supplier β”‚ β”‚
β”‚ C β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚
β”‚ O β”‚ β”‚ β”‚ β”‚
β”‚ N Don't β”‚ ACL β”‚ Conformistβ”‚ β”‚
β”‚ T Control β”‚ (always) β”‚ or β”‚ β”‚
β”‚ R β”‚ β”‚ ACL β”‚ β”‚
β”‚ O β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ L β”‚
β”‚ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Decision Tree​

Example Decisions​

IntegrationControlModel QualityPatternReasoning
Orders β†’ InventoryYesGoodCustomer-SupplierWe can influence Inventory team
Orders β†’ StripeNoGoodConformist or ACLStripe's model is well-designed
Orders β†’ Legacy CRMYesPoorACLProtect from legacy mess
Identity β†’ AllYesGoodOHSMany consumers

Decision 3: Subdomain Investment​

Investment Allocation Framework​

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ SUBDOMAIN INVESTMENT MATRIX β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ β”‚
β”‚ CORE SUBDOMAIN β”‚
β”‚ β”œβ”€β”€ Engineering: Best engineers, dedicated team β”‚
β”‚ β”œβ”€β”€ Architecture: Full DDD, possibly Event Sourcing β”‚
β”‚ β”œβ”€β”€ Testing: Comprehensive, property-based β”‚
β”‚ β”œβ”€β”€ Documentation: Extensive, living docs β”‚
β”‚ └── Investment: 60-70% of engineering effort β”‚
β”‚ β”‚
β”‚ SUPPORTING SUBDOMAIN β”‚
β”‚ β”œβ”€β”€ Engineering: Competent engineers, shared team OK β”‚
β”‚ β”œβ”€β”€ Architecture: Simpler patterns, CRUD acceptable β”‚
β”‚ β”œβ”€β”€ Testing: Standard coverage β”‚
β”‚ β”œβ”€β”€ Documentation: Adequate β”‚
β”‚ └── Investment: 20-30% of engineering effort β”‚
β”‚ β”‚
β”‚ GENERIC SUBDOMAIN β”‚
β”‚ β”œβ”€β”€ Engineering: Any level, integration focus β”‚
β”‚ β”œβ”€β”€ Architecture: Use vendor's patterns β”‚
β”‚ β”œβ”€β”€ Testing: Integration tests only β”‚
β”‚ β”œβ”€β”€ Documentation: Vendor docs + integration notes β”‚
β”‚ └── Investment: 5-10% of engineering effort β”‚
β”‚ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Classification Checklist​

For each subdomain, answer:

Core Indicators (3+ = Core):

  • Provides competitive advantage
  • Customers choose us because of this
  • Requires deep domain expertise
  • Changes frequently based on market
  • Would be valuable to competitors

Supporting Indicators (3+ = Supporting):

  • Necessary for business operations
  • Similar across companies in industry
  • Stable requirements
  • Could describe to other companies
  • No off-the-shelf solution fits perfectly

Generic Indicators (3+ = Generic):

  • Same problem every company faces
  • Multiple commercial solutions exist
  • Well-understood, stable problem
  • No competitive advantage possible
  • Building custom would be wasteful

Decision 4: Technology Selection​

Fitness Function Approach​

Define what "good" looks like for each context:

// Example: Fitness functions for Orders Context
public class OrdersContextFitnessFunctions
{
// Performance: Order placement < 200ms p99
[Fitness("Order placement latency")]
public bool OrderPlacementLatency() =>
Metrics.GetP99("order.place.latency") < TimeSpan.FromMilliseconds(200);

// Reliability: 99.9% success rate
[Fitness("Order success rate")]
public bool OrderSuccessRate() =>
Metrics.GetSuccessRate("order.place") > 0.999;

// Consistency: No orphaned orders
[Fitness("Order consistency")]
public bool NoOrphanedOrders() =>
Database.Query<Order>(o => o.Status == "pending" && o.Age > TimeSpan.FromHours(1))
.Count() == 0;
}

Technology Decision Matrix​

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ TECHNOLOGY SELECTION BY SUBDOMAIN β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ β”‚
β”‚ CORE SUBDOMAIN β”‚
β”‚ β”œβ”€β”€ Database: Depends on requirements β”‚
β”‚ β”‚ β€’ Event Sourcing? β†’ EventStoreDB, Marten β”‚
β”‚ β”‚ β€’ Complex queries? β†’ PostgreSQL β”‚
β”‚ β”‚ β€’ High write throughput? β†’ Cassandra β”‚
β”‚ β”œβ”€β”€ Language: Team's strongest language β”‚
β”‚ β”œβ”€β”€ Framework: Minimal, domain-focused β”‚
β”‚ └── Deployment: Independent, own lifecycle β”‚
β”‚ β”‚
β”‚ SUPPORTING SUBDOMAIN β”‚
β”‚ β”œβ”€β”€ Database: PostgreSQL (default), or managed β”‚
β”‚ β”œβ”€β”€ Language: Team standard β”‚
β”‚ β”œβ”€β”€ Framework: Full-featured OK β”‚
β”‚ └── Deployment: Can share infrastructure β”‚
β”‚ β”‚
β”‚ GENERIC SUBDOMAIN β”‚
β”‚ β”œβ”€β”€ Database: Whatever vendor provides β”‚
β”‚ β”œβ”€β”€ Language: Whatever SDK is best β”‚
β”‚ β”œβ”€β”€ Framework: Vendor's recommended β”‚
β”‚ └── Deployment: SaaS when possible β”‚
β”‚ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Decision Documentation: ADRs​

Architecture Decision Record Template​

# ADR-001: Orders Context Boundary

## Status
Accepted

## Context
We need to define the boundary for order management functionality.
Currently, order-related code is spread across multiple modules.

## Decision
Create a dedicated Orders bounded context that owns:
- Order placement and modification
- Order status and lifecycle
- Order lines and pricing at time of order

The context will NOT own:
- Product catalog (Catalog context)
- Inventory levels (Inventory context)
- Payment processing (Payments context)

## Consequences

### Positive
- Clear ownership for Orders team
- Independent deployment
- Focused domain model

### Negative
- Need integration with Inventory for stock checks
- Need integration with Payments for checkout
- Some data duplication (product info at order time)

### Risks
- Over-fetching from other contexts
- Eventual consistency challenges

## Alternatives Considered

### Alternative 1: Merge with Inventory
Rejected because: Different change rates, different team expertise

### Alternative 2: Smaller boundary (just order placement)
Rejected because: Would fragment order lifecycle

Strategic Decision Checklist​

Before finalizing strategic decisions:

Boundary Decisions​

  • Scored each boundary on 5 dimensions
  • Boundaries align with team structure
  • Each boundary has clear ownership
  • Ubiquitous language is consistent within boundaries
  • Integration points are identified

Integration Decisions​

  • Pattern chosen for each integration
  • ACL used for external/legacy systems
  • OHS defined for multi-consumer scenarios
  • Contract testing planned

Investment Decisions​

  • Each subdomain classified (Core/Supporting/Generic)
  • Core subdomains have dedicated teams
  • Generic subdomains use existing solutions
  • Resource allocation matches classification

Technology Decisions​

  • Fitness functions defined
  • Technology matches subdomain type
  • Team has required skills
  • Migration path exists

Staff+ Interview Questions​

Q: How do you make strategic DDD decisions?

A: I use a systematic framework:

  1. Discovery first - Event Storming, interviews, domain analysis
  2. Score boundaries - Linguistic, team, change, data, consistency
  3. Classify subdomains - Core, Supporting, Generic
  4. Choose integration patterns - Based on control and model quality
  5. Document decisions - ADRs with context and consequences
  6. Validate continuously - Fitness functions, retrospectives

Q: How do you handle disagreements about boundaries?

A: I facilitate data-driven discussions:

  1. Use the scorecard - Makes discussion concrete
  2. Try both - Prototype with different boundaries
  3. Defer to team - Who will own and maintain it?
  4. Accept uncertainty - Boundaries can evolve
  5. Document reasoning - Future team understands why

Q: What's the biggest strategic DDD mistake you've seen?

A: Treating everything as core. Teams apply full DDD with Event Sourcing to generic subdomains like authentication or email sending. This wastes engineering effort and adds unnecessary complexity. The fix: ruthlessly classify subdomains and match investment to classification.

Quick Reference Card​

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ STRATEGIC DECISIONS QUICK REFERENCE β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ β”‚
β”‚ BOUNDARY ANALYSIS β”‚
β”‚ Score: Linguistic + Team + Change + Data + Consistency β”‚
β”‚ >20/25 = Strong boundary β”‚
β”‚ β”‚
β”‚ INTEGRATION PATTERN β”‚
β”‚ Control + Good Model β†’ Customer-Supplier β”‚
β”‚ No Control + Good Model β†’ Conformist β”‚
β”‚ Poor Model β†’ ACL (always) β”‚
β”‚ Many Consumers β†’ OHS β”‚
β”‚ β”‚
β”‚ INVESTMENT ALLOCATION β”‚
β”‚ Core: 60-70%, best engineers, full DDD β”‚
β”‚ Supporting: 20-30%, simpler patterns β”‚
β”‚ Generic: 5-10%, buy/outsource β”‚
β”‚ β”‚
β”‚ DOCUMENT WITH ADRs β”‚
β”‚ Context β†’ Decision β†’ Consequences β†’ Alternatives β”‚
β”‚ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Next Steps​