I have read the PPP book and clean code, coder and architecture books.
I know that:
So I assume that clean architecture does not force being close layered and it allows being open layered, meaning that for example UI which is in the frameworks layer can directly access Entity, jumping 2 layers in the way.
And I understand that if clean architecture forced being close layered, we could not implement repository interface directly from Frameworks layer and we should implement it in the terms of next layer and this next layer should have implemented it in the terms of its next layer and so on.
Now my question is, why we can't introduce Entity
as the parameter type of the usecase or controller directly and why do we have to define data structures or DTOs in the middle layers and bother converting entity to data structures and return it as response, while we are allowed to use and see Entity
in the controller layer because the access rule is not violated?
Consider this example, suppose we have:
JobView
JobController
JobUseCase(RequestModel) : ResponseModel
JobEntity
Now if JobView
wants to call JobController
, it should pass RequestModel
. Now could we simply introduce JobEntity
as the RequestModel
like so:
JobView
JobController
JobUseCase(JobEntity)
JobEntity
I know that doing like so will increase the fragility of code, because that way if we change JobEntity
, then JobView
has to change. But does clean architecture force SOLID principles being fragile or rigid as a rule?!
Uses Cases as the Units of Work In practice, a use case is just a function (a query or a command) that should ideally be pure — deterministic and without side effects. Side effects are supposed to be delegated. A use case is like an algorithm to accomplish a client-driven task. ( Clean Architecture for the rest of us)
Adapters are just “language translators”. The remaining part of the infrastructure is what remains when you take out the adapters: drivers, MVC frameworks, web frameworks, filesystem APIs, and any other mechanisms that bridge into external systems. They're not your code so we can ignore them for now.
In Clean Architecture "use case" and "interactor" means the same: it is the component which contains business logic. The presenter in this architecture does not contain any business logic.
In the layered architecture pattern, entities is put in the Persistence layer. But in clean architecture, Domain-driven Design, Hexgonal architecture, entities is pulled up to the Domain layer. This way will seperate the dependence of Domain layer to the Persistence layer.
Why not using entity as request model of usecase?
You have answered this question yourself: Even as you do not break the dependency rule, it will increase the fragility of the code.
why we cant introduce Entity as the Parameter type of usecase or controller directly and why we have to define data structures or DTOs in the middle layers and bother converting entity to data structures and return it as response , while we are allowed to use and see Entity in the Controller layer because the access rule is not violated?
The (Critical business) Entities and the DTOs are in the application of very different reasons. Entities should encompass the critical business rules and have nothing to do with communication between adapters and interactors. DTOs should be implemented in the most convenient way to enhance this communication, and don't have any immediate reason to depend on business entities.
Even as an entity might have the exact same code as a DTO, this should be considered coincidence, as their reason to change are completely different (Single responsibility principle). This might seems to collide with the popular DRY principle (Dont repeat yourself), but DRY states that knowledge should not be duplicated, code might still look the same in different parts of the application as long as they are changed by different reasons.
The above answers are accurate, but I'd like to point out why this creates confusion as I've seen it before: because from a dependency perspective, there is nothing wrong with passing entities across the boundaries. What you cannot pass is any type that has a dependency on an outer layer, that's a no-no for reasons obvious. Much of the book talks about dependency issues, so that creates confusion - why aren't the entities ok?
As stated above, entities need to observe SRP just like any other code. If you use entities for data transfer purposes, you have introduced an unnecessary coupling. When the entity needs to change for a business reason, at the very least the mapping code and maybe more in the outer layer need to change in response.
Not sure I understand the reasoning behind your question:
Does clean architecture forces SOLID principles or not being fragile or rigid as a rule?
How could Clean Architecture possibly force rigidity and fragility? Defining an architecture is all about: how to take care widely of fundamental OOP principles such as SOLID and others…
On the other hand, your following example would definitely denature Clean Architecture:
JobView
>
JobController
>
JobUseCase(JobEntity)
>
JobEntity
This implicitly tells us that you've retrieved your entity most likely from the controller, which completely misses the point of the Interactor (or use case) and so of the Clean Architecture.
Interactors encapsulate application business rules such as interactions with entities and CRUD on entities done via the Entity Gateway which in turn encapsulate the infrastructure layer.
Furthermore, in Clean Architecture context, your entities which are parts of your model layer should have nothing to do with your controller which is part of your delivery mechanism, or more exactly, which is the evaluator of the HTTP request message. Denaturing this way the lower level component that is the controller would affect negatively the SRP (=> fragility increase) and the degree of decoupling between your components (=> rigidity increase).
You say:
And I understand that if clean architecture forced being close layered, we could not implement repository interface directly from Frameworks layer and we should implement it in the terms of next layer and this next layer should have implemented it in the terms of its next layer and so on.
Your entity framework's RepositoryInterface
and its implementations belong to the infrastructure layer and they should be wrapped, adapted by the entity gateway. Law of Demeter might be important to respect here as we are talking about the business model's closed layer's port (EntityGatewayInterface
)'s implementation.
Finally, for the reasons above, I suspect the following assumption being wrong and so would be all the further assumptions based on that one, leading yourself to total confusion:
So I assume that clean architecture does not force being close layered and it allows being open layered, meaning that for example UI which is in the frameworks layer can directly access Entity, jumping 2 layers in the way.
But whether it forces being closed layered or not, Clean Architecture explicitly and concretely defines itself (relation between components) such as on the UML class diagram below:
I can see only a close layered architecture from that diagram…
It seems to me that an open layer is an oxymore, that it does not constrain what a layer is supposed to constrain by nature, because by definition, a layer is an isolation, an abstraction of a group of components reduced to its port, meant to reduce technical debt such as fragility etc...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With