8
votes

In Domain-Driven Design, the domain layer is said to have no dependency on other layers, i.e. the repository interface is within the domain layer, while its implementation is at the infrastructure layer.

However, the bounded context (with domain + infra) is deployed as one unit (deployable) so the layers are actually logical and not physical. Then what is the advantage of drawing this virtual separator between domain and infrastructure layers?

Update

In a traditional layered approach, the domain (service) is said to be dependent on the infrastructure layer. Conversely, when it comes to DDD / Clean / Hexagonal architectures the domain is independent of other layers because the domain layer has an interface that is implemented by the infrastructure layer.

Whether you use DDD or a traditional layered approach, you still have to mock repositories, meaning the domain is not actually independent. Is this correct?

2

2 Answers

6
votes

The assumption behind the Domain Model pattern is that the Domain Model is either the most complex part of the application, or the part that changes more frequently than other parts.

The Domain Model pattern attempts to address this concern by making the Domain Model independent of other concerns. One of the advantages of doing this is that you can unit test the Domain Model in isolation of its dependencies. You can also vary the domain model without having to change other parts of the application.

Those are the main advantages, but there are disadvantages as well. Decoupling can make the code base harder to navigate, and will also tend to require a lot of mapping between layers. Whether or not this is worthwhile depends on specific circumstances (how complex is the Domain Model, what other verification alternatives do you have, etc.)

7
votes

The biggest driver is to allow the different layers to change without affecting each other. For example, I often test my domain layer independently of my infrastructure layer. I do this by mocking out my DAOs and Repositories, this allows my tests to run much faster, and makes them far less brittle.

I've also used it when my repository ends up needing a new implementation (Oracle vs MS SQL vs Web Service). It massively reduces your complexity when you don't have to rewrite your entire application when a back-end service changes out from under you.

Finally, splitting this tends to help you accomplish SRP. Integrating your database layer into your domain layer tends to allow you to skip this (at least in my experience). It doesn't force you to, but it certainly encourages bad behaviors.

It's the same reason we don't write our domain logic in our UI. For any sufficiently small example, it's a waste of time. It's value only becomes apparent when you have a large, complex application.