Reading Notes: Introduction to Domain-Driven Design
→ 日本語版を読むOverview
Notes from reading Introduction to Domain-Driven Design.
There may be mistakes, so please refer to the book for accurate information.
Key Points
Domain-Driven Design is a design methodology in which you gain knowledge about the domain of the problem you are trying to solve while designing.
Object-oriented programming is one of its important elements, and this book focuses on explaining design patterns.
Modeling, which pairs with patterns, is barely covered in this book. The focus is on learning the knowledge needed to develop with Domain-Driven Design.
Design Patterns
The following patterns are introduced. If you forget something, re-reading the book is a good idea.
- Value Object
- Entity
- Domain Service
- Repository
- Application Service
- Factory
- Aggregate
- Specification
Rather than using primitive types such as string, use classes that represent domain-specific values — Value Objects. For example, instead of using an int type to represent money, create a money class.
Value Objects need to be comparable. For the money class, if the amount and currency are the same, they are considered equal.
They also need to be immutable and interchangeable. Once a money class is instantiated, the attributes of the instance cannot be changed (immutability).
If you want to change a value, you need to create an instance with a different value and replace the existing instance.
Entities, on the other hand, are mutable and are distinguished even if they have the same attributes. Thinking about a user class makes entities easier to understand. A username can change. And even if two users have the same username, they are not necessarily the same user. Entities have such characteristics. The criterion for something being an entity (as opposed to a Value Object) is whether it has a lifecycle. Concepts like users that are created and eventually deleted are considered entities.
Value Objects and entities are called domain objects. Domain objects have behaviors defined within them, such as character count and character type checks. The properties and constraints of values and entities themselves are written inside the domain object class.
On the other hand, constraints between domain objects are written in domain services (classes). For example, if duplicate usernames are not allowed, create a UserService class and perform the duplicate check in the domain service.
The repository is used for interaction with the data store. If you write data store access directly inside business logic (UserApplicationService, application service), it becomes difficult to understand the processing. Therefore, create a repository interface (IUserRepository) and write the concrete processing in a concrete class (UserRepository). In the business logic code, operations are performed against the interface. This follows the Dependency Inversion Principle. UserApplicationService depends on IUserRepository, and UserRepository also depends on IUserRepository.