mirror of
https://github.com/s-frick/effigenix.git
synced 2026-03-28 19:10:22 +01:00
5.1 KiB
5.1 KiB
DDD Rules Checklist
Use this checklist to validate your domain model against DDD principles.
Aggregate Rules
Boundaries
- Aggregate has a clearly defined boundary
- Aggregate Root is identified and documented
- Only Aggregate Root is accessible from outside
- Child entities are encapsulated (not exported or accessed directly)
- Aggregate is the smallest consistent unit
Invariants
- All invariants are documented with
// Invariant:comments - Constructor validates all invariants
- Every mutation method maintains invariants
- Invalid state is impossible to create
- Aggregate rejects invalid operations (returns error)
References
- No direct object references to other Aggregates
- References to other Aggregates use ID only
- ID references are typed (not raw strings/ints)
- Cross-aggregate consistency is eventual (not immediate)
Transactions
- One Aggregate = one transaction boundary
- No multi-aggregate transactions in domain layer
- Application layer coordinates multiple aggregates if needed
Sizing
- Aggregate is not too large (performance issues)
- Aggregate is not too small (consistency issues)
- "Just right" - protects business invariants, nothing more
Entity Rules
Identity
- Has a unique identifier
- ID is assigned at creation time
- ID is immutable after creation
- ID type is specific (e.g.,
AccountID, notstring)
Equality
- Equals compares by ID only
- Two entities with same ID are considered equal
- Attribute changes don't affect equality
Mutability
- State changes through explicit methods
- No public setters
- Methods express domain operations (not CRUD)
- Methods return errors for invalid operations
Value Object Rules
Immutability
- All fields are private/unexported
- No setter methods
- No methods that modify internal state
- "Modification" creates new instance
Equality
- Equals compares ALL fields
- Two VOs with same values are interchangeable
- No identity concept
Validation
- Constructor validates input
- Invalid VOs cannot be created
- Returns error for invalid input
- Provides
MustXxx()variant for tests (panics on error)
Self-Containment
- VO contains all related logic
- Domain logic lives in VO methods
- Example:
Money.Add(other Money) Money
Repository Rules
Interface Location
- Repository interface defined in domain layer
- Implementation in infrastructure layer
- Domain doesn't know about infrastructure
Methods
- Methods operate on Aggregates (not entities)
Save(aggregate)- persists aggregateFindByID(id)- retrieves aggregate- No methods that bypass Aggregate Root
Transactions
- Repository doesn't manage transactions
- Application layer manages transaction scope
- One repository call = one aggregate
Domain Service Rules
When to Use
- Operation spans multiple aggregates
- Operation doesn't naturally belong to any entity/VO
- Significant domain logic that's not entity behavior
Implementation
- Stateless (no instance variables)
- Named after domain operation (e.g.,
TransferService) - Injected dependencies via constructor
- Returns domain objects, not DTOs
Domain Event Rules
Naming
- Past tense (e.g.,
AccountCreated,TransferCompleted) - Describes what happened, not what to do
- Domain language, not technical terms
Content
- Contains all data needed by handlers
- Immutable after creation
- Includes aggregate ID and timestamp
Publishing
- Events raised by Aggregates
- Published after aggregate is saved
- Handlers in application or infrastructure layer
Clean Architecture Rules
Dependency Direction
- Domain layer has no external dependencies
- Application layer depends only on Domain
- Infrastructure depends on Domain and Application
- No circular dependencies
Layer Contents
- Domain: Entities, VOs, Aggregates, Repository interfaces, Domain Services
- Application: Use Cases, Application Services, DTOs
- Infrastructure: Repository implementations, External services, Framework code
Interface Segregation
- Small, focused interfaces
- Defined by consumer (domain layer)
- Implemented by provider (infrastructure)
Common Anti-Patterns to Avoid
Anemic Domain Model
- ❌ Entities with only getters/setters
- ❌ All logic in services
- ✅ Rich domain model with behavior
Large Aggregates
- ❌ Loading entire object graph
- ❌ Too many entities in one aggregate
- ✅ Small, focused aggregates
Aggregate References
- ❌
order.Customer(direct reference) - ✅
order.CustomerID(ID reference)
Business Logic Leakage
- ❌ Validation in controllers
- ❌ Business rules in repositories
- ✅ All business logic in domain layer
Technical Concepts in Domain
- ❌
@Entity,@Columnannotations - ❌ JSON serialization tags
- ✅ Pure domain objects, mapping in infrastructure