Slice of business problem (Core/Supporting/Generic)
Core domain
Competitive differentiator; invest most effort
Supporting
Custom but non-differentiating
Generic
Buy or use OSS (auth, billing)
Bounded context
Code boundary for one model
Ubiquitous language
Shared terms in each context
2. Designing Bounded Contexts
Heuristic
Apply When
Same term, different meaning
"Order" in Sales vs Fulfillment → 2 contexts
Different teams
Conway's law alignment
Different lifecycle
Different deploy cadence
Different storage
OLTP vs analytics
3. Designing Context Mapping
Pattern
Relationship
Partnership
Two teams succeed/fail together
Shared Kernel
Small shared model; high coordination
Customer-Supplier
Upstream serves downstream needs
Conformist
Downstream conforms with no influence
Anti-Corruption Layer
Translation layer to protect model
Open Host Service
Public protocol for many consumers
Published Language
Shared schema (Avro, OpenAPI)
Separate Ways
No integration; duplicate as needed
4. Designing Ubiquitous Language
Element
Practice
Source
Domain experts; not engineers alone
Glossary
Maintain per bounded context
Code mirrors language
Class/method names match domain terms
Refactor on rename
Update code when language evolves
5. Designing Aggregates and Aggregate Roots
Rule
Description
Single root
One entity is the root; access only via root
Transactional boundary
One aggregate per transaction
Reference by ID
Other aggregates referenced by ID, not object
Small aggregates
Reduces contention, lock scope
Invariants
Enforced inside aggregate boundary
Example: Aggregate root (Java)
public class Order { // root private final OrderId id; private final List<OrderLine> lines = new ArrayList<>(); private OrderStatus status; public void addLine(ProductId pid, int qty, Money price) { if (status != OrderStatus.DRAFT) throw new IllegalStateException(); lines.add(new OrderLine(pid, qty, price)); // invariant managed via root } public Money total() { return lines.stream().map(OrderLine::subtotal).reduce(Money.ZERO, Money::add); }}
6. Designing Domain Events
Property
Description
Past tense name
OrderPlaced, PaymentCaptured
Immutable
Facts about what happened
Carries data
Self-contained payload + metadata
Versioned
Schema evolution required
Outbox pattern
Persist event in same DB txn as state
7. Designing Anti-Corruption Layer
Component
Role
Translator
Maps external model → domain model
Adapter
Talks to external API/legacy
Facade
Simplified domain-friendly interface
Note: Use ACL when integrating with legacy/3rd-party systems whose model would pollute yours. Adds latency and code; worth it for protection.