Domain modeling, DDD and CQRS
Putting the rule in the domain, not in the controller or in the procedure. An entity that protects its own invariant, explicit state transitions, and commands separated from queries.
The most direct proof is public
Nobody outside can read the corporate code, so what backs this skill are the packages I published. PMQ.Domain has entities with identity equality, aggregate roots, value objects and domain events. PMQ.Mediator has a behavior pipeline and validation integration. They are on NuGet, with 1,864 downloads on the most downloaded of the suite, and the code is open.
Declarative validation is the default in what I write: the rule lives in the type, not scattered across the service that uses it.
What I do
- Model aggregates with the invariant protected in the type itself, instead of validating in the service
- Implement state transitions as ordered, explicit rules, where the order of the clauses is the precedence
- Separate commands from queries, with one handler per use case and a validation pipeline before execution
- Use the notification pattern: a violated business rule returns an accumulated notification, not an exception
- Emit domain events at the point of change and react outside the main flow
- Write value objects for what the system treats as a concept, not as a string
The decision I stand by
Validation as data instead of exception. An exception interrupts the flow and returns the first error, and the real operation wants to return every problem at once. A broken business rule is an expected outcome, not a program failure. That is why PMQ.Notifications exists, and it is the decision that ties the whole suite together.
Where I applied it
Payments and anti-fraud · Experience · Industrial monitoring
What I have not done yet
I have not applied event sourcing or CQRS with a physically separate read store. My CQRS is separation of responsibility inside the same database, which solves the organization problem and not the read scaling one.