In this blog post you can find my general rules for implementing system using Domain Driven Design. Don’t use them blindly but it’s good starting point for DDD practitioners.
- Separate bounded context for each important module of the application (important from business partner perspective).
- Independent of each other (if feasible).
- For monolithic application separate Spring Framework context for each bounded context, e.g:
- CRUD like bounded contexts (user management, dictionaries, etc.) should be implemented as Anemic Domain Model.
- Place for application business logic.
- Must be independent of the technical complexity, move technical complexity into infrastructure.
- Must be independent of the particular presentation technology, move presentation related stuff into web.
- Internal package structure must reflect business concepts (bounded contexts), e.g:
- Rich model, place for: entities, domain services, factories, strategies, specifications, etc.
- Best object oriented practices applied (SOLID, GRASP).
- Unit tested heavily (with mocks in the last resort).
- Unit tests executed concurrently (on method or class level).
- Meaningful names for domain services e.g:
- Domain services dependencies are injected by constructor.
- Having more than 2~3 dependencies is suspicious.
- Entities aren’t managed by containers.
- Aggregate root entities are domain events publishers (events collectors).
- Aggregates in single bounded context might be strongly referenced (navigation across objects tree).
- Aggregates from different bounded contexts are referenced by business keys (if feasible).
- No security, no transactions, no aspects, no magic, only plain old Java.
- Interfaces for domain services when the service is provided by infrastructure.
- No interfaces for domain services implemented in the domain model itself.
- Orchestrator and facade for actors under Model.
- Place for security handling.
- Place for transactions handling.
- Must not deliver any business logic, move business logic into domain model. Almost no conditionals and loops.
- Implemented as transactional script.
- No unit tests.
- Acceptance tests executed against this layer.
- Cglib proxied, proxy must be serialized by session scoped beans in web layer.
- Dependencies are injected on field level (private fields).
- Ten or more dependencies for single application service isn’t a problem.
- Application services are also domain event listeners.
- Always stateless.
- No interfaces, just implementation.
- Initial application data.
- Loaded during application startup (fired by
BootstrapEvent) if application storage is empty.
- Loading order is defined with Spring
- Data is loaded within Model API.
- Data might be loaded within application services, e.g: load sample Excel when application is integrated with external world this way.
- No tests, bootstrap is tested during application startup on daily basis.
- Place for technical services
- Must not deliver any business logic, move business logic into domain.
- Internal package structure must reflect technical concepts, e.g:
- Shared for all bounded context of the application. For more complex applications, separate technical services e.g:
- Class names must reflect technical concepts, e.g.:
- Integration tested heavily (with Spring Framework context loaded).
- Integration tests executed by single thread.
- Test execution separated from unit tests within test groups.
- Separate Spring Framework context for each technical concept, e.g:
- Separate and independent Spring test context for each technical module, e.g:
- Client specific facade (REST, MVC, JSF, etc.)
- Delegates requests to application services
- No transactions, no method level security, move security and transactions to application services.
- No business logic, move business logic into domain.
- Tested with mocked application services.
- Tested with loaded spring context for MVC controllers (if applicable).
- Serializable session scoped beans (to be safe all beans in this module should be
- Internal package structure must reflect UI organization structure, it might be similar to project sitemap.
- Top level package might reflect technology or architecture e.g: