Cleaner Architecture?


First result on Google Search says:

The Clean Architecture is a software architecture proposed by Robert C. Martin (better known as Uncle Bob).
This architecture is similar to the Onion-Hexagonal-DCI-Architecture proposed by their respective authors.
The base of this architecture is to follow and obey rules of the ‘Dependency Rule’.

Let’s extract the important bits:

  • The author is Robert C. Martin
  • It’s similar to other architectures:
    • Onion: consists of several concentric layers interacting with each other towards the core, which is the domain.
    • Hexagonal: helps shift the main focus to the business domain while spending less time on the technical aspects of it.
    • Data, context and interaction (DCI): an event-driven programming paradigm, where some event triggers a use case.
  • It aims to follow the ‘Dependency Rule’, which states that “dependencies can only point inwards”.w

On paper, the Clean Architecture works as per this famous image:

the clean architecture scheme

Input comes from various sources: Web, Devices, UI, etc. Then, data is received by the controller, processed by the usecase and finally returned to the caller through the presenter.

The folder structure would look something like this:

project
|_ domain
|_ infrastructure
|  |_ db
|  |_ webservice
|  |_ provider
|_ interface
|  |_ controller
|  |_ presenter
|_ usecase
   |_ interactor

The domain folder contains the basic domain’s entities and their repositories’ interface/contracts.

The Infrastructure collects all those pieces of code that know which protocols to use to retrieve and store data: third party providers, HTTP web-services, databases etc.

The interface folder is the most confusing bit. It sounds like it should only contain interfaces/contracts of what is then implemented elsewhere, but the name stands for its literal definition:

Interface: a point where two systems, subjects, organizations, etc. meet and interact.

The usecase folder, finally, is the core of the business logic. This layer contains reusable logic, that defines how data will be processed when the “user” interacts with the service.

As we all know too well, reality often differs from the beauty of the theory. Here’s a list of common patterns that are built on the idea of the Clean Architecture and branch out to a custom usage.

This approach drops the infrastructure folder, in favor of putting everything within the interfaces folder. In languages that support interfaces/contracts, this creates a bit of confusion, since both interfaces and their implementations are in the same folder.

mad mr incredible meme

As previously mentioned, some might debate that the interface folder should only contains interfaces/contracts, when the programming language supports it.
This approach makes the code more intuitive, since all the interfaces are within a single package/folder. When using the interface folder this way, all the implementations are usually stored in the infrastructure.

When the domain’s entities and their repositories were first separated from each other, this approach was born. Usually, the repositories are moved either in the interfaces, the infrastructure or in both folders (split as interface/contract and implementation). Useful when there are a lot of entities divided in subdomains or entities that do not require a repository.

Ever thought the usecase folder needed to be beefier? Look no further than this approach, where both presenters and controllers are included under the usecase folder. Putting together all the “do-er” (i.e. controller, interactor, presenter), might sound like a personal choice of style, but it’s used to collect all the input logic within the same folder.

Usually based upon the previous variant, this one embeds the interactor and presenter logic within the controller’s. This monolithic logic creates a single and large point of processing for the input data. It works well for proof of concepts or rushed services, but it is in no mean maintainable, testable or readable.

xbit meme

At some point, someone needed entities in the usecase and thought about adding a domain folder in there. Then, interfaces/contracts were needed, which brought in the interface folder.

This led to each folder of the clean architecture structure having the clean architecture structure within itself. The approach inception ensures that each folder is structured in a predictable way, but imports are extremely confusing and the “clean” aspect of the architecture is lost in the recursion.

Whether you use it as intended or in any of its other variations, the Clean Architecture is a great paradigm and definitely worth including in your projects.

Like many other things in software engineering, it is subject to manipulation and changes. Everyone might bend it to fit their views and their style: either by improving it or simplifying it.

Both are valid options and should be taken into consideration when starting a new project.

Stay tuned for a detailed example on how a Golang projects looks like when using the Clean Architecture.