📜 ⬆️ ⬇️

Misconceptions Clean Architecture

Turn circles into blocks


At first glance, Clean Architecture is a fairly simple set of recommendations for building applications. But I, and many of my colleagues, strong developers, did not immediately realize this architecture. And recently, in chat rooms and the Internet, I see more and more erroneous ideas associated with it. With this article, I want to help the community better understand Clean Architecture and get rid of common misconceptions .


Just want to make a reservation, delusions - this is a personal matter. Everyone has the right to err. And if it suits him, then I do not want to interfere. But it is always good to hear the opinions of other people, and often people do not even know the opinions of those who stood at the origins.


Origins


In 2011, Robert C. Martin , also known as Uncle Bob, published an article on Screaming Architecture , which states that architecture should “shout” about the application itself, and not about what frameworks it uses. Later an article appeared in which Uncle Bob repulses those who speak out against ideas of pure architecture. And in 2012 he published an article “ The Clean Architecture ”, which is the main description of this approach . In addition to these articles, I also highly recommend watching the video of Uncle Bob's speech.


Here is the original diagram from the article that first pops up in the developer’s head when it comes to Clean Architecture:


Original scheme


In the Android community, Clean began to quickly gain popularity after the article Architecting Android ... The clean way? written by Fernando Cejas. I first learned about Clean Architecture from her. And only then went to look for the original. In this article, Fernando cites the following layer scheme :


The scheme from Fernando Cejas


The fact that there are other layers on this scheme, and some other Interactors and Boundaries lie in the domain layer is confusing. The original picture is also not clear to everyone. The articles are ambiguous or slightly abstract. And not everyone watches the video (usually due to lack of knowledge of English). And now, because of misunderstanding, people start to invent something, complicate, be mistaken ...


Let's figure it out!


Clear architecture


Clean Architecture has combined the ideas of several other architectural approaches, which agree that the architecture should :



This is achieved by splitting and following the Dependency Rule (dependency rule).


Dependency Rule


Dependency Rule tells us that inner layers should not depend on outer layers . That is, our business logic and application logic should not depend on presenters, UI, databases, etc. On the original diagram, this rule is depicted by arrows pointing inward.


The article says: the names of entities (classes, functions, variables, anything) declared in the outer layers should not be found in the code of the inner layers .


This rule allows you to build systems that will be easier to maintain, because changes in the outer layers will not affect the inner layers.


Layers


Uncle Bob highlights 4 layers:



In more detail, what are these layers, we will look at the course of the article. For now we will stop on data transmission between them.


Transitions


Transitions between layers are made through Boundaries , that is, through two interfaces: one for the request and one for the answer. They can be seen on the right side of the original scheme (Input / OutputPort). They are needed so that the inner layer does not depend on the outer layer (following the Dependency Rule), but at the same time it can transfer data to it.


The flow of data on the original scheme


Both interfaces belong to the inner layer (note their color in the image).


See, the Controller calls the method on InputPort, it is implemented by UseCase, and then UseCase returns the response to the OutputPort interface, which implements the Presenter. That is, the data crossed the border between the layers, but all the dependencies point inward to the UseCase layer.


In order for the dependency to be directed towards the reverse data flow, the principle of dependency inversion is applied (the letter D from the abbreviation SOLID ). That is, instead of UseCase directly dependent on Presenter'a (which would violate the Dependency Rule), it depends on the interface in its layer, and Presenter must implement this interface.


Exactly the same scheme works in other places, for example, when AccessCase is accessing the Gateway / Repository. In order not to depend on the repository, the interface is selected and put on the UseCases layer.


As for the data that crosses the boundaries, it should be simple structures . They can be passed as DTO or be wrapped in a HashMap, or simply be arguments to the method call. But they must be in the form more convenient for the inner layer (to lie in the inner layer).


Features of mobile applications


It should be noted that Clean Architecture was invented with a slightly different type of application on the mind . Large server applications for large businesses, rather than mobile client-server applications of medium complexity, which do not need further development (of course, there are different applications, but you must admit, in the greater mass they are just that). Failure to understand this can lead to overengineering .


On the original scheme is the word Controllers. It appeared on the diagram because of the frontend, in particular from Ruby On Rails. They often share the Controller, which processes the request and delivers the result, and Presenter, which outputs this result to the View. Many do not immediately guess, but in Android applications, Controllers are not needed .


Even in the article Uncle Bob says that layers do not have to be 4 . There may be any number, but the Dependency Rule should always be applied.


Looking at the scheme from the article Fernando Cejas, one might think that the author took advantage of this opportunity and reduced the number of layers to three. But it is not. If you understand, then in the Domain Layer it contains both Interactors (this is another name for UseCases) and Entities.


We are all grateful to Fernando for his articles, which gave a good impetus to the development of Clean in the Android community, but his scheme also gave rise to a misconception.


Misconception: Layers and Linearity


Comparing the original scheme from Uncle Bob and the scheme of Fernando Cejas, many are confused. The linear scheme is perceived easier, and people begin to misunderstand the original. But without understanding the original, they begin to misinterpret and linear. Someone thinks that the arrangement of the inscriptions in circles has a sacred meaning, or that the Controller should be used, or they are trying to correlate the names of the layers on two schemes. It is ridiculous and sad, but the main schemes have become the main sources of error!


We will try to fix it. To begin, let's clear the basic scheme , removing from it too much for us. And rename Gateways to Repositories, because this is the more common name for this entity.


Simplified original layout


It became a little clearer. Now we do this: cut the layers into parts and turn this scheme into a block scheme, where the color will still denote the belonging to the layer.


Turn circles into blocks


As I said above, colors denote layers. And the bottom arrow indicates Dependency Rule.


In the resulting scheme, it is easier to imagine the flow of data from the UI to the database or server and back. But let's take another step towards linearity by arranging the layers into categories :


Layers by category

I deliberately do not call this separation layers, unlike Fernando Cejas. Because we already divide the layers. I call it categories or parts. You can call it whatever you like, but you should not reuse the word "layers".


And now let's compare what happened with the Fernando scheme.


Comparison with Fernando Cejas Scheme

I hope now all began to fall into place. I said above that, in my opinion, Fernando still has 4 layers. I think now it has also become clearer. In the Domain part we have and UseCases and Entities.


This scheme is perceived easier. After all, usually the events and data in our applications go from the UI to the backend or database and back. Let's picture this process:


Data flow from UI and back

Red arrows indicate data flow .


The event of the user goes to Presenter, that transfers in Use Case. Use Case makes a request to the Repository. Repository gets data somewhere, creates an Entity, passes it to UseCase. So Use Case gets all the Entity he needs. Then, applying them and his logic, he gets the result, which he sends back to Presenter. And that, in turn, displays the result in the UI.


On transitions between layers (not categories, but layers marked with different colors), the Boundaries described earlier are used.


Now that we have understood how the two schemes relate , let's consider the following misconception.


Fallacy: Layers, Not Entities


As is clear from the title, someone thinks that the diagrams depict entities (this especially affects UseCases and Entities). But it is not.


The diagrams depict layers, they may contain many entities . They will contain interfaces for transitions between layers (Boundaries), various DTO, main layer classes (Interactors for UseCases layer, for example).


It will not be superfluous to look at the diagram, assembled from the parts shown in the video of Uncle Bob's performance. It shows classes and dependencies :


Scheme of classes from the speech Uncle Bob


See the double lines? These are the boundaries between the layers. The separation between the layers of Entities and UseCases is not shown, since the video focused on the fact that all logic (applications and business) is fenced off from the outside world.


We are already familiar with Boundaries, the interface of Gateway is the same. Request / ResponseModel is just a DTO for transferring data between layers. According to the rule of dependence, they must lie in the inner layer, which we see in the picture.


About the Controller, we also said, it does not interest us. Its function is performed by Presenter.


And the ViewModel in the picture is not a ViewModel from MVVM or a ViewModel from Architecture Components . This is just a DTO for transferring the View data so that the View is stupid and just meshes with its fields. But these are implementation details and will depend on the choice of the presentation pattern and personal approaches.


The UseCases layer contains not only Interactors, but also Boundaries for working with the presenter, an interface for working with the repository, and DTO for inquiry and response. From this we can conclude that the original scheme still reflects the layers .


Misconception: Entities


Entities rightfully occupy the first place by incomprehension .


Not only that almost no one (including me until recently) is aware of what it really is, but they are also confused with the DTO.


Once in a chat, I had a dispute in which my opponent argued to me that Entity is objects received after parsing JSON in the data layer, and DTO are objects that Interactors operate on ...

We will try to understand well, so that no one else has such errors.


What is Entities?


Most often, they are perceived as POJO classes that Interactors work with. But it is not. At least not quite.


In the article, Uncle Bob says that Entities encapsulate business logic , that is, everything that does not depend on a particular application, but will be common to many . But if you have a separate application and it is not sharpened by some existing business, then the Entities will be the business objects of the application, containing the most general and high-level rules .


I think it is the phrase: “Entities are business objects,” most confuses. In addition, in the above diagram, Interactor gets Entity from Gateway from the video. It also reinforces the feeling that these are just POJO objects.


But the article also says that Entity can be an object with methods or a set of structures and functions . That is, the emphasis is on the importance of methods, not data.


This is also confirmed in the explanation from Uncle Bob, which I recently found:
Uncle Bob says that for him Entities contain business rules that are independent of the application. And they are not just objects with data. Entities may contain references to objects with data, but their main purpose is to implement business logic methods that can be used in various applications .


And about the fact that Gateways return Entities in the picture, he explains the following:
The Gateway implementation retrieves data from the database, and uses it to create the data structures that will be transferred to the Entities, which Gateway will return. Implemented it can be a composition


class MyEntity { private MyDataStructure data;}


class MyEntity extends MyDataStructure {...} 

, :


And remember, we are all pirates by nature; and the rules I'm talking about here are really more like guidelines…
( : , , , , …)

, , . - , .


, Entities :



, , Entities UseCases, .


: UseCase / Interactor


UseCase Interactor. : « Interactor ». : « Interactor’e UseCase?».


Interactor’a , . :


«...interactor object that implements the use case by invoking business objects.»


:


Interactor – , use case ( ), - (Entities).


Use Case ?
Uncle Bob «Object-Oriented Software Engineering: A Use Case Driven Approach», Ivar Jacobson 1992 , , Use Case.


Use case – , , .


, :


Use Case

Use Case , .


, , . .


– Use Case’a, – .


:



Ivar Jacobson Use Case , ControlObject.
Uncle Bob , , Controller MVC Interactor. , UseCase.
.


, Interactor use case execute() , . .


.


- , Interactor’a – . . .


Interactor’ , use case’.
, , . Interactor’, .


: « – UseCase’», – . . , UseCase Interactor , .


Interactor UseCase, : Interactor/UseCase – , use case ( ).


, , -, , – Repository.



- , . Uncle Bob Gateway, Repository.


Repository


Repository? , , ( Fernando Cejas ), .


Repository - . , , .


Android- Repository , .


Hannes Dorfmann’.


Gateway


Repository, «» , login() (, Repository, – , ).


, Gateway – , . Gateway , API . , , .


«», .


Repository/Gateway Interactor?


, . !
Repository Interactor.


, , , Repository Presenter’a, Interactor.


Repository , Dependency Rule Repository . – Interactor . Interactor, , , proxy-interactor’, , .


, , Interactor, , , Interactor , . .


:


, . .


DTO Entities . , . Dependency Rule .


– . .


DTO :



DTO Enitities:



.


:


, / , ( ). , API . , , .


: Interactor’e


, . , c:
So when we pass data across a boundary, it is always in the form that is most convenient for the inner circle.
( , )


Interactor .
Interface Adapters, Presenter Repository.


?


. API . , login() Profile OrderState. , , Repository.


LoginResponse Profile OrderState , Interactor’e Repository?


Interactor’e. , .. .


Repository. :



Interactor, , .


Interactor Repository?


Interactor Repository. , « Repository/Gateway Interactor?».


Clean Architecture .
:



, , . , . .


RxJava Clean Architecture


Android- RxJava. , Fernando Cejas , RxJava Clean Architecture.


, , , , Boundaries ( Dependency Rule) Observable Subscriber.


, RxJava , . , – Clean Architecture.


, RxJava . Java 9 util.concurrent.Flow, Reactive Streams, RxJava2. - RxJava, .


: Clean Architecture MVP?


, ? .
:



: Clean Architecture


. Google Architecture Components.


- . . .


, – . , , , . , .


, , .


!


. . Clean Architecture, , , « »!


')

Source: https://habr.com/ru/post/335382/


All Articles