← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

Domain-Driven Design (DDD)

architecture PHP 5.0+ Advanced
debt(d7/e7/b7/t7)
d7 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'only careful code review or runtime testing' (d7). The detection_hints note that phpstan is listed but automated detection is explicitly 'no'. The code pattern (classes named with technical terms instead of domain language; anemic domain model) requires human judgment and careful code review to identify — no tool can reliably detect that your naming doesn't align with business vocabulary or that you've missed bounded contexts.

e7 Effort Remediation debt — work required to fix once spotted

Closest to 'cross-cutting refactor across the codebase' (e7). The quick_fix says to start with ubiquitous language — renaming classes and methods to match business vocabulary. But the common_mistakes show systemic issues: wrong bounded contexts, missing domain expert collaboration, patterns applied without domain understanding. Correcting a DDD misapplication (e.g., one giant bounded context, anemic models throughout) touches multiple layers and files across the entire codebase, well beyond a single-component fix.

b7 Burden Structural debt — long-term weight of choosing wrong

Closest to 'strong gravitational pull' (e7, scored b7). DDD applies to web, cli, and queue-worker contexts — it shapes every layer of the application. The choice of bounded contexts, aggregates, and ubiquitous language defines how every future feature is modelled and where code lives. Every change is shaped by the domain model structure, and a poorly applied DDD (e.g., one bounded context for everything) imposes a persistent productivity tax on all work streams.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap' (t7). The canonical misconception is explicit: developers believe DDD means using repositories, aggregates, and value objects everywhere, when DDD is primarily about aligning software with business language and boundaries. This directly contradicts how most developers encounter DDD (through its tactical patterns in blog posts and frameworks), causing them to over-engineer CRUD with patterns while missing the actual point. The common mistakes confirm this is a widely recurring, costly misunderstanding.

About DEBT scoring →

Also Known As

DDD domain modelling tactical DDD strategic DDD

TL;DR

An approach to software development that focuses on modelling the core domain using the language and concepts of domain experts.

Explanation

DDD (Eric Evans, 2003) advocates building a rich domain model using the Ubiquitous Language — a shared vocabulary between developers and domain experts. Key building blocks: Entities (objects with identity), Value Objects (immutable, equality by value), Aggregates (consistency boundaries), Repositories (data access abstraction), Domain Services (stateless domain logic), Domain Events, and Bounded Contexts (explicit boundaries between subdomains). In PHP, DDD is applied by separating the domain layer from infrastructure, avoiding anemic domain models, and letting domain experts drive the naming and structure.

Diagram

flowchart TD
    subgraph STRAT[Strategic Design]
        BC[Bounded Contexts]
        CM[Context Map]
        UL[Ubiquitous Language]
        BC --- CM --- UL
    end
    subgraph TACT[Tactical Design]
        AGG[Aggregates]
        ENT[Entities]
        VO[Value Objects]
        DOM[Domain Events]
        REPO[Repositories]
        AGG --> ENT & VO
        AGG --> DOM
        REPO -->|persists| AGG
    end
    STRAT -->|shapes| TACT
style AGG fill:#6e40c9,color:#fff
style VO fill:#238636,color:#fff
style DOM fill:#d29922,color:#fff

Common Misconception

DDD means using repositories, aggregates, and value objects everywhere. DDD is primarily about aligning software with business language and boundaries — the tactical patterns (aggregates, repositories) are optional tools, not the point.

Why It Matters

DDD aligns the software model with the business domain, giving developers and domain experts a shared language — code that matches the business vocabulary is easier to reason about, evolve, and hand off.

Common Mistakes

  • Applying DDD to simple CRUD applications — the overhead of aggregates, repositories, and domain events is rarely justified.
  • Not developing a ubiquitous language with domain experts — the code uses different words than the business, causing miscommunication.
  • Starting with the technical patterns (aggregates, events) without first understanding the domain — patterns without domain knowledge produce over-engineered CRUD.
  • One bounded context for the entire application — contexts that are too large defeat the purpose.

Code Examples

✗ Vulnerable
// Database-shaped domain model — not DDD:
class UserRow {
    public int $id;
    public string $email;
    public int $status_id; // Foreign key — not domain language
    public ?int $billing_address_id;
    // Shaped by the database, not the domain
}
✓ Fixed
// DDD building blocks in PHP

// Entity — has identity, mutable state
class Order {
    public function __construct(private OrderId \$id) {}
    public function getId(): OrderId { return \$this->id; }
}

// Value Object — no identity, immutable, compared by value
readonly class Money {
    public function __construct(
        public int \$amount,
        public string \$currency,
    ) {}
    public function equals(Money \$other): bool {
        return \$this->amount === \$other->amount && \$this->currency === \$other->currency;
    }
}

// Domain Service — logic that doesn't naturally fit an entity
class PricingService {
    public function calculateTotal(Order \$order, TaxRate \$rate): Money {}
}

// Repository — collection abstraction over persistence
interface OrderRepository {
    public function find(OrderId \$id): ?Order;
    public function save(Order \$order): void;
}

Added 15 Mar 2026
Edited 19 Apr 2026
Views 38
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 0 pings F 0 pings S 1 ping S 0 pings M 0 pings T 1 ping W 0 pings T 0 pings F 0 pings S 2 pings S 0 pings M 0 pings T 0 pings W 1 ping T 3 pings F 0 pings S 1 ping S 0 pings M 0 pings T 1 ping W 0 pings T 0 pings F 0 pings S 1 ping S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F
No pings yet today
No pings yesterday
Perplexity 9 Amazonbot 9 Ahrefs 4 ChatGPT 3 Unknown AI 3 SEMrush 2 Google 1 Majestic 1
crawler 31 crawler_json 1
DEV INTEL Tools & Severity
🔵 Info ⚙ Fix effort: High
⚡ Quick Fix
Start with the ubiquitous language — name your classes and methods using the business domain's vocabulary, not technical terms
📦 Applies To
PHP 5.0+ web cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
Classes named with technical terms (DataManager, DbHandler) instead of domain language; anemic domain model
Auto-detectable: ✗ No phpstan
⚠ Related Problems
🤖 AI Agent
Confidence: Low False Positives: High ✗ Manual fix Fix: High Context: File Tests: Update

✓ schema.org compliant