The universe is built on a plan the profound symmetry of which is somehow present in the inner structure of our intellect." *- Paul Valery.
Clean Architecture is great! Let's try that again…Clean Architecture is beautiful!
Clean Architecture is symmetric! Clean Architecture is natural! Clean Architecture should really be common sense!
Clean Architecture is the structure that naturally emerges when truly applying DIP: "High level modules should not depend on low level modules. Both should depend on abstractions"
"High level modules" is about the most important part of an application implementation. It's about the policies of the application, the general abstractions that govern the entire application; it's about the truths that do not vary when the details are changed.
By contrast, "low level modules" is about the details. These are generic technical mechanisms that support the high level modules: logging, OOM, ORM, email, sms…
The traditional Layers pattern violates DIP and by doing so it involves some unfortunate consequences.
For decades, we have been structuring applications using Layers. For decades, Layers have been synonym with good application architecture - you either had layers or you had the BBOM (Big Ball of Mud anti-pattern)
For decades, we have claimed to fully apply SOLID but the truth is we did not. At most, we have been applying SOLI.
At least in the .NET world, Layers violates DIP by imposing a reference from the high level assemblies to the low level assemblies which are part of the Infrastructure layer:
Simply put, Clean Architecture conforms to DIP, Layers does not.
Clean basically concentrates the most important part of an application implementation in the core, while it externalizes all the details.
The powerful principle that makes this pattern work is called the dependency rule: "Source code dependencies can only point inwards". This is in fact a more pragmatic definition of DIP.
If you imagine an asymmetric model derived from classical Layers but conforming to DIP it would look something like the following:
The arrows represent source code dependencies, not call chains.
The fact that Clean Architecture representation is symmetric using the concentric circles is not a coincidence. It may not be so obvious, but it hides a very powerful principle: all the details are just details!
Clean Architecture focuses on the most important part of an application implementation. This is the application core and this is what DIP has been referring to as "high level modules" for over a decade. And from the point of view of the application core, the delivery framework is nothing more special than the database or the logging framework.
This is why Clean Architecture drives development towards a "domain - out" approach and feels like a more comfortable house for Domain Driven Design in general. This is why delaying the decisions on technologies feels more natural when using the Clean Architecture. It's the very mental model imposed by the concentric circles that makes you see the forest for the trees.
In my view, Cone Architecture is just a better metaphor for this type of software structure. And yes, I came up with that term and no, it's not popular.
It involves two different perspectives: if you look at it from above, you see some concentric circles governed by the dependency rule that source code dependencies can only point inwards. That's a pure technical view.
But if you look at it from aside, you can clearly see what DIP means by "high level modules" and "low level modules". You can now clearly infer the layers hierarchy by their level of abstraction. The inner circles are higher level than the outer circles.
The longer version of this article including more details and examples is available here.