Clean Architecture Is Wrong
Well, not hugely wrong. But still not entirely correct as I see it. This inconsistency has been bothering me for a little while. It’s not a big deal but something to be aware of.
And this flaw does not take away from the utility of Clean Architecture as a software engineering philosophy in any substantive way. I still firmly believe that Clean Architecture—for all its abstractness and potential flaw—leads to beautifully simple application designs that can be easily modified and extended. What’s not to love?
All right, let’s get into it.
Here is the familiar schematic diagram for Clean Architecture.
The Dependency Rule states that inner circles cannot know about outer ones. On the other hand, outer shells must depend on inner ones. In the end, some circles must know about one another, or it’s not a productive program but merely chunks of unconnected code.
So, outer rings know about inner ones, and the little arrows depict this one-way relationship:
Use Cases know about Entities—Entities are unaware of Use Cases.
Interface Adapters know about Business Logic—Business Logic is ignorant of Interface Adapters.
Frameworks & Devices are aware of Interface Adapters, yet Interface Adapters are oblivious to Frameworks & Devices.
I have a problem with the last statement. I believe it to be wrong.
Let’s assume the statement is correct and that Frameworks really are dependent on Interface Adapters.
Say, in a system, we use SQL Server as our database technology.
It would mean that our generic SQL Server data access SDK should reference, or depend on, our specific data access code to retrieve data from our SQL Server database!
Inversely, our specific SQL Server data access could not call generic SQL Server data access functions to fetch or save data since there exists no reference! How is our application-specific data access mean to do its job?
In my opinion, the dependency should be the other way around between the outermost layers.
The Interface Adapters shell connects interfaces exposed by Business Logic with those of the general code of Frameworks, libraries and SDKs.
Adapters act as connectors between two dissimilar interfaces. To see as much, take a look at that adapter plug you’re using to connect the toaster/TV/microwave you bought in the UK to your power outlet. It has both a male and female plug interface. The toaster does not need to know about the UK adapter, and neither does your power outlet—neither depends on the adapter. On the other hand, the power adapter depends on both UK and local power outlet interfaces.
Adapters always depend on both interfaces. Yet, the things that an adapter connects do not, by themselves, depend on the adapter.
Therefore, it stands to reason that within the context of Clean Architecture, Interface Adapters depend on Business Logic interfaces and the outermost Frameworks circle.
That’s it. I hope that makes sense.
What do you think? Am I missing something? Feel free to comment or send your opinion to email@example.com. I want to learn and see where I am going wrong! :-)