Protecting the domain by Victor Rentea
talk on youtube
Most important principles :
- Single Responsibility
- Dependency inversion
- DRY
Testing tools
- Archunit java
- equivalent in php : https://github.com/qossmic/deptrac
- https://github.com/j6s/phparch : best
- https://github.com/mihaeu/dephpend
- https://github.com/carlosas/phpat
Domain vs
- DDD : domain driven development
- encapsulates a specific part of the business code (entities, services ..)
- higher level code than infrastructure
Infrastructure
- backend code
- lower level code
- implementations
Protect the domain
Keep the domain safe from any external influence. Defend the domain ! Agnostic.
Defend it from someone else when you call lower level code
domain logic should not depend on infrastructure
Keep core logic independent of UI
independent of DB, no vendor lock ins, no stored procedures, no too complicated sql
independent of external APIs
is an orm intrusive ? not necessarily
logic should be built on objects you have full control on
DTOs are enemies
they are
- bloated
- flat
- different perspective
should be replaced by ids, value objects and events
Testing
- Tests should test the domain
Domain communication and calls
Options
- RPC
- Queue
- FTP
- DB
To communicate between those 2
- Create an interface
- Create an adapter in the domain
- Client code depends on the domain
Multiple domains
Possible to have multiple domains (e.g. product and user)
Modularizing the monolith
Protecting from the database ? is database the enemy ? not necessarily
Read clean architecture
Do we need application + domain + architecture ?
No we can use application which is also architecture (pragmatic onion architecture aka hexagonal aka ports and adapters aka clean architecture)
Monolith vs micro services
- micro services is slow to build
- monolith is fast but should be modular
monolith should be broken down after some time
Breaking it down
- organize your code by entities ! like order.service and not service.order
- instead of linking entities use literal id and get the entity from the other side
- or use a value object
- cut the link from 2 domains
- communication using a common domain events (or event folder per domain) but any events can be accessed by any domain
- never using directly entities or services
- test by using arch unit and having less and less violations
- use Value Object (VO) instead of DTOs
- Sometimes you can create a Order object in Customer domain, “duplicating” the class name but it’s good because it doesn’t serve the same goal
Bounded context
Read https://matfrs2.github.io/RS2/predavanja/literatura/Avram%20A,%20Marinescu%20F.%20-%20Domain%20Driven%20Design%20Quickly.pdf or here
When 2 contexts have different expectations you should create a bounded context and so create multiple class Chickens for example and disperse the fields in each entity.
Anti corruption layer
Make sure nothing from outside goes inside
In frontend : MVVM viper architecture : read
Event driven ?
events or direct service calls ?
if no return expected -> events potentially over queue
event = asynchronous message queue, propaget change
fetch data over GET (sync RPC)
DDD uses a lot domain events
Tests
- Test DSL : for end to end