Domain-Driven Design
Requirementsβ
Here are the core requirements:
- A searchable catalog of Freelancer must be provided
- The new solution must allow to store the different Communication Channels available to contact a Freelancer
- A searchable catalog of Projects must be provided
- A searchable catalog of Customers must be provided
- The Timesheets for the Freelancers under contract must be maintained
First Approachβ
Common Mistakeβ
The whole solution is a big code smell, an anemic domain model.
- It is a very big object graph. If they do not use Hibernate/ JPA lazy loading here, it will pretty sure run out of memory under heavy load
- Why is the association between User and Role bi-directional?
- The ContactType has some boolean flags to show what type is it, email, phone, mobile
- The Freelancer class holds a list of Projects. This also means that Projects cannot be added without modifying the Freelancer object. This can cause transaction failure under heavy load, as possibly multiple users are adding Projects for the same Customer.
- What does ContactInformation mean? The requirements stated βCommunication Channelβ. Is it the same?
The DDD wayβ
Break it down to Subdomains
- Identity and Access Management Subdomain
- Freelancer Management Subdomain
- Customer Management Subdomain
- Project Management Subdomain The separated Domain can easily be visualized. In DDD terms this is called a Context Map, and it is the starting point for any further modeling.
Create Bounded Context
The new Big Pictureβ
There are now Bounded Contexts for every identified Subdomain. The Bounded Contexts are isolated, they know nothing of each other. They are only glued together by a set of common types, like UserId, ProjectId and CustomerId. This helps us to eliminate unwanted side effects.
Designing behavior using Domain Driven Designβ
Wrong Approachβ
Correct Approachβ
This is much better. There is now an explicit Address class, which encapsulates the whole address state.
Application Architectureβ
Every Deployment Unit contains the following parts:
- A Domain Layer
- An Infrastructure Layer
- and an Application Layer
The Domain Layer contains the infrastructure independent domain logic as we modeled before in this example. The Infrastructure Layer provides the technology dependent artifacts, like the Hibernate based FreelancerRepository implementation. The Application Layer acts as a gateway to business logic with integrated transaction control.
Using this style of architecture, the Domain Layer of our business logic does not depend on anything. We can change the Repository implementations from Hibernate to JPA or even NoSQL ones like Riak or MongoDB for instance without affecting any business logic.