The use of computer systems becomes increasingly present and essential in society. From everyday tasks - such as ordering meals on the phone - to performing imaging exams, software is used. To maintain this growing demand, it is necessary to produce and maintain software within appropriate costs, aiming at its growth and optimization without compromising what has already been developed.
Software engineering is an engineering discipline that is concerned with all aspects of software production, having as main activities the specification, development, validation and evolution of software (SOMMERVILLE, 2010). As software is abstract and not limited to physical laws, this simplifies software engineering. Just as this simplification gives the developer power to build applications optimally, the lack of constraint can also make software complex and difficult to maintain.
As physical buildings are made up of smaller components like brick, concrete or wood, software buildings are made up of software components that are made up of other software components, and both types of buildings have an architecture behind them in order to keep that structure firm and secure. A key software engineering concept for this article is software architecture. The software architecture of a program or computer system is the structure or structures of the system, which covers the software components, the externally visible properties of these components and the relationships between them (BASS; CLEMENTS; KAZMAN, 2012).
The changes that occur during software development are inevitable, and a good architecture aims to reduce the time to execute these changes, which consequently reduces financial costs and effort. An architecture must, in addition to meeting the immediate demands of users, developers and owners, also meet these expectations over time (MARTIN, 2017).
Just as in building architecture there are different architectural styles, such as classic, romantic or baroque, in software architecture there are architectural types such as Client-server Architecture, Onion Architecture and Clean Architecture. However, every software architecture has the common objective of dividing the software into layers, having at least one layer for the business rules and one for the user and system interfaces (MARTIN, 2017).
An architecture must not only meet the demands of users, developers, and owners at a given time, but also meet those expectations over time. Robert MARTIN (2017) proposed Clean Architecture with the aim of promoting the implementation of cohesive systems, independent of technology and favoring code reusability. Next, we'll look at this architecture in more detail.
The concept of Clean Architecture was defined by Robert C. Martin (MARTIN, 2017) in his book entitled “Clean Architecture: A Craftsman's Guide to Software Structure and Design”. In this architecture, systems can be divided into two main elements: the policies and the details. The policies are the business rules and procedures, and the details are the items necessary to carry out the policies. (MARTIN, 2017) It is from this division that Clean Architecture begins to differentiate itself from other architectural patterns. The architect must create a way for the system to recognize the policies as the main elements of the system, and the details as irrelevant to the policies.
In the clean architecture, it is not necessary to choose the database or framework at the beginning of the development, as all these are details that do not interfere with the policies and, consequently, can be changed over time.
In Clean Architecture there is a well-defined division of layers. The architecture is framework-independent, i.e., the internal layers that contain the business rules do not depend on any third-party library, which allows the developer to use a framework as a tool and not adapt the system to meet the specifications of a particular technology. Other benefits of Clean Architecture are: testability, UI independence, database independence and independence from any external agents (business rules should not know anything about the interfaces of the external world).
To illustrate all these concepts, the diagram shown in the figure below was created.
Each layer in the figure represents a different area of the software, the innermost part being the policies and the outermost the mechanisms.
The main rule for Clean Architecture is the Dependency Rule, which says that the dependencies of a source code can only point inwards, that is, in the direction of the highest level policies. That said, we can say that elements of an innermost layer cannot have any information about elements of an outermost layer. Classes, functions, variables, data format, or any entity declared in an outer layer must not be mentioned by the code of an inner layer.
The innermost layer is the Entities layer, which contains the application's business objectives, containing the most general and highest level rules. An entity can be a set of data structures and functions or an object with methods, as long as that entity can be used by multiple applications. This layer must not be altered by changes in the outermost layers, that is, no operational changes in any application should influence this layer.
The use case layer contains the application-specific business rules, grouping and implementing all the use cases of the system. Use cases organize the flow of data to and from entities and guide entities in applying crucial business rules to achieve use case goals. This layer should also not be affected by the outermost layers, and your changes should not affect the entities layer. However, if the details of a use case change, some of the code in that layer will be affected.
The interface adapters layer has a set of adapters that convert the data to the most convenient format for the layers around it. In other words, it takes data from a database, for example, and converts it to the most convenient format for the entity layers and use cases. The reverse path of conversion can also be done, from the data from the innermost layers to the outermost layers. Presenters, views, and controllers belong to this layer.
The outermost layer of the diagram is usually made up of frameworks and databases. This layer contains the code that establishes communication with the interface adapters layer. All the details are in this layer, the web is a detail, the database is a detail. All these elements are located in the outermost layer to avoid the risk of interfering with the others (MARTIN, 2017).
But if the layers are so independent, how do they communicate? This contradiction is resolved with the Dependency Inversion Principle. Robert C. MARTIN (2017) explains that you can organize the interfaces and inheritance relationships so that the source code dependencies are opposite the control flow at the right points.
If a use case needs to communicate with the presenter, this call cannot be straightforward as it would violate the Dependency Rule, so the use case calls an interface from the inner layer and the presenter in the outer circle does the implementation. This technique can be used between all layers of the architecture. The data that travels between the layers can be basic structures or simple data transfer objects, these data being just arguments for function calls. Entities or records from the databases must not be transmitted in order not to violate the Dependency Rule.
There is no architecture that is the "silver bullet" and can solve all problems. And it's not Clean Architecture that came to this.
Once the application base has been created, Clean Architecture helps to maintain and evolve the application without requiring much cost (either physical or time). This help is provided by the fact that its layers are independent and by the constant use of design patterns. Thus, changes to a certain part of the system tend not to interfere with the operation of the rest of the application.
On the other hand, a more experienced team of developers is needed to work on the system. It takes knowledge of design patterns to be able to maintain and structure the software. It also takes longer than a simple MVP application to see the first results, so it's important to have strong client alignment to make the future benefits clear.
Finally, it is concluded that for applications that tend to grow and remain for many years, the Clean Architecture approach is a good solution to use. However, for simple and non-evolving systems, it may not be worth the effort with such an architecture, being wiser to follow simpler architectural patterns.
- SOMMERVILLE, Ian. Software Engineering. 9. ed. Harlow, England: Addison-Wesley, 2010. ISBN 978-0-13-703515-1.
- BASS, Len; CLEMENTS, Paul; KAZMAN, Rick. Software Architecture in Practice. 3rd. ed. [S.l.]: Addison-Wesley Professional, 2012. ISBN 0321815734.
- MARTIN, Robert C. Clean Architecture: A Craftsman’s Guide to Software Structure and Design. 1st. ed. USA: Prentice Hall Press, 2017. ISBN 0134494164.