Die Domäne modellieren
Worum es bei DDD wirklich geht - das Geschäftsmodell in den Mittelpunkt zu stellen - und die gemeinsame Fachsprache, die Code, Gespräch und Domäne synchron hält.
Deutsche Übersetzung in Arbeit
Diese Lektion ist noch nicht ins Deutsche übersetzt und wird daher auf Englisch angezeigt. Der Rest der Seite ist vollständig lokalisiert.
Auf dieser Seite
Domain-Driven Design (DDD), from Eric Evans's 2003 book, is a big topic with a reputation for heavy ceremony. This module takes the lite path: the handful of ideas that make code better even without adopting the whole methodology. The most fundamental is this - the hard part of software isn't usually the technology, it's understanding the business precisely enough to model it. DDD puts that model at the center.
The domain is the point
In ledger-legacy, the important complexity isn't the database or the HTTP layer - it's the accounting rules:
what a transaction is, when a fee applies, how balances reconcile, what "posted" versus "pending" means. That
knowledge is the domain, and it lives in the heads of domain experts (accountants), often poorly reflected
in code that's organized around tables and controllers instead of accounting concepts.
DDD's core move: make the domain model the heart of the software. Not an afterthought buried in service
methods, but an explicit, first-class model - classes named Ledger, Posting, ReconciliationPeriod that
behave like the real concepts, with the business rules living inside them. When the model matches how experts
think, changes to the business map cleanly onto changes in code.
Ubiquitous language
The keystone practice is the ubiquitous language: a shared vocabulary, used identically by developers and
domain experts, in conversation, documentation, and code. No translation layer. If accountants say "post a
transaction," the code has ledger.post(transaction) - not txnManager.processRecord(dto).
Why it matters: every translation between "business speak" and "developer speak" is a place bugs hide. When an accountant says "reversal" and a developer hears "delete," they've silently agreed on different behavior. A ubiquitous language eliminates that gap:
// Code that speaks the ubiquitous language - an accountant could read the method names
class Ledger {
Posting post(Transaction txn) { ... }
Reversal reverse(Posting original, Reason reason) { ... } // 'reverse', not 'delete'
Balance balanceAsOf(LocalDate date) { ... }
}The language is living: when you discover a concept the model lacks (say, "a transaction can be disputed"), you add it to both the conversation and the code, together. The code becomes documentation the experts can validate.
A model is bound to a context
The ubiquitous language is only consistent within a boundary - what DDD calls a bounded context (a later lesson). 'Account' means one thing to the lending team and another to the marketing team, and forcing one global model produces a Frankenstein class serving no one well. So 'ubiquitous' means 'consistent within this context', not 'universal across the whole company'. Hold that thought - it's the strategic payoff at the end of the module.
Model-code fit
The senior insight is that the model and the code must evolve together. A pretty UML diagram that diverges
from the code is worse than useless - it lies. In DDD, the code is the model: refining your understanding of
the domain means refactoring the classes, and a refactor that makes the code clearer often reveals a domain
insight ("oh, a pending posting isn't really a Posting yet - it's a PendingEntry"). Design and discovery
are the same activity.
Imagine a construction project where the architect speaks 'design' and the builders speak 'construction,' and a translator shuttles between them redrawing everything. Every redraw introduces errors - a load-bearing wall becomes decorative in translation. DDD is insisting architect and builders work from one shared blueprint in one shared language: when the architect says 'cantilever,' the builders read 'cantilever,' and when a builder finds the cantilever won't work, they amend the same blueprint everyone uses. The model isn't a document that decays in a drawer - it's the living thing both sides build from.
In ledger-legacy, accountants talk about 'settling' a transaction (finalizing it so funds actually move), but
the code has TransactionService.updateStatus(txn, 3) where 3 is a magic status code meaning settled. A recent
bug happened because a developer thought status 3 meant 'archived.' Explain what's wrong through a DDD lens, and
sketch the fix.
What is the 'ubiquitous language' in Domain-Driven Design?
Key takeaways
- DDD puts the business domain model - not the database or framework - at the center of the software.
- The hard complexity is usually understanding the business precisely; DDD makes that model explicit and first-class, with rules living inside domain classes.
- The ubiquitous language is a shared vocabulary used identically by developers and domain experts in conversation, docs, and code.
- Every translation between business-speak and developer-speak is where bugs hide; matching the code's names to the experts' words closes that gap.
- The model and code evolve together - the code IS the model - and the language is consistent within a bounded context, not globally universal.