Core Building Blocks¶
The Core Building Blocks of Domain-Driven Design (DDD) are fundamental concepts that help structure and model complex software systems around the business domain.
- Entities
- Value Objects
- Aggregates (Aggregate & Aggregate Root)
- Repositories
- Services
- Domain Events
- Factories
- Modules
Clean Architecture is a layered architecture that emphasizes separation of concerns and dependency inversion. It consists of the following layers:
- Domain Layer implements the core, use-case independent business logic of the domain/system.
- Application Layer implements the use cases of the application based on the domain. A use case can be thought as a user interaction on the User Interface (UI).
- Presentation Layer contains the UI elements (pages, components) of the application.
- Infrastructure Layer supports other layer by implementing the abstractions and integrations to 3rd-party library and systems.
Business Logic places into two layers, the Domain layer and the Application Layer, while they contain different kinds of business logic;
DDD mostly focuses on the Domain & Application Layers and ignores the Presentation and Infrastructure. They are seen as details and the business layers should not depend on them.
That doesn't mean the Presentation and Infrastructure layers are not important. They are very important. UI frameworks and database providers have their own rules and best practices that you need to know and apply. However these are not in the topics of DDD.
Clean Architecture provides a high-level structure for organizing code, while DDD focuses on modeling the business domain. When combined, they create a robust, maintainable, and domain-aligned system.
This section introduces the essential building blocks of the Domain & Application Layers.
Domain Layer Building Blocks¶
- Entity: An Entity is an object with its own properties (state, data) and methods that implements the business logic that is executed on these properties. An entity is represented by its unique identifier (Id). Two entity object with different Ids are considered as different entities.
- Value Object: A Value Object is another kind of domain object that is identified by its properties rather than a unique Id. That means two Value Objects with same properties are considered as the same object. Value objects are generally implemented as immutable and mostly are much simpler than the Entities.
- Aggregate & Aggregate Root: An Aggregate is a cluster of objects (entities and value objects) bound together by an Aggregate Root object. The Aggregate Root is a specific type of an entity with some additional responsibilities.
- Repository (interface): A Repository is a collection-like interface that is used by the Domain and Application Layers to access to the data persistence system (the database). It hides the complexity of the DBMS from the business code. Domain Layer contains the
interface
s of the repositories. - Domain Service: A Domain Service is a stateless service that implements core business rules of the domain. It is useful to implement domain logic that depends on multiple aggregate (entity) type or some external services.
- Specification: A Specification is used to define named, reusable and combinable filters for entities and other business objects.
- Domain Event: A Domain Event is a way of informing other services in a loosely coupled manner, when a domain specific event occurs.
- Factories: Responsible for creating complex objects or aggregates.
Application Layer Building Blocks¶
- Application Service: An Application Service is a stateless service that implements use cases of the application. An application service typically gets and returns DTOs. It is used by the Presentation Layer. It uses and coordinates the domain objects to implement the use cases. A use case is typically considered as a Unit Of Work.
- Data Transfer Object (DTO): A DTO is a simple object without any business logic that is used to transfer state (data) between the Application and Presentation Layers.
- Unit of Work (UOW): A Unit of Work is an atomic work that should be done as a transaction unit. All the operations inside a UOW should be committed on success or rolled back on a failure.