Domain Driven Design: Layers
Developing applications that can perform complex tasks can be a challenging process, and it requires careful planning and design. One approach to managing this complexity is to use a Layered Architecture. This architecture separates the application's code into layers, each with a specific responsibility and purpose. These layers are typically organized in a hierarchy, with higher-level layers depending on lower-level layers.
In Domain Driven Design (DDD), a popular software development approach, there are four layers in the architecture: the domain layer, application layer, infrastructure layer, and user interface (UI) layer. The domain layer contains the business logic and rules that define the application's behavior. The application layer coordinates the interactions between the domain and infrastructure layers. The infrastructure layer provides the necessary services and infrastructure for the application, such as databases, message queues, and web servers. Finally, the UI layer provides the interface for users to interact with the application.
Domain Driven Design
Domain Drive Design layers
One of the key features of Layered Architecture is that the dependencies between layers are inward-facing. This means that higher-level layers can only depend on lower-level layers. For example, the domain layer can only depend on other code within the domain layer. The application layer can depend on the domain layer and other code within the application layer, but it cannot depend on the UI layer.
By separating the application's code into layers and using inward-facing dependencies, developers can manage complexity and ensure that each layer has a well-defined responsibility. This can make it easier to modify and maintain the application over time, as changes in one layer do not affect other layers.
Let's try to understand the responsibility of each layer.
The layer of business logic that should implement reality reflecting business processes. Since this layer is where abstractions are made, the design of interfaces are included in the domain layer. An important factor is that objects do not have too many technical details, such as a database connection (does not depend on how and where the objects are stored).
The business domain model should be written using the ubiquitous language, which should be understandable for both those who know technical vocabulary and those who do not know it. Each business model should have a clearly defined Bounded Context.
The application layer is responsible for creation and retrieval of domain objects, as well as calling their methods to satisfy user commands. It is the layer where business process flows are handled, execution of work commands and reactions to domain events are coded.
The application layer could also be seen as the service layer of your application. It can contain service classes that help with executing business rules on aggregates in your domain layer. It will load an aggregate from the domain repository, run an operation on the aggregate, and if the operation was successful, persist the aggregate again. The application layer can also handle the collecting and dispatching of domain events so other systems can listen in on the changes that have happened in your domain.
The infrastructure layer is responsible for communication with external websites, access to data (persistence storage) or to other resources. This layer will be the layer that accesses external services such as database, messaging systems and email services. The interface designed in the domain layer and used in the application layer will be implemented in this layer and gain an identity. Pieces of code that will be executed to communicate with the outside world such as network and file system are located in this layer.
This layer is the part where interaction with external world happens. It ca be used to implement controllers that handle incoming HTTP requests.
Please remember that there is no single way to design an application architecture. These principles certainly help but feel free to adjust them when it better fits your needs.
Layered Architecture is a useful approach to managing the complexity of developing applications that can perform complex tasks. By organizing the code into layers and defining clear boundaries between them, developers can create more robust and maintainable applications. Additionally, this approach can make it easier to test the application, as each layer can be tested independently of the others.