What is the main idea behind Clean Architecture and what situations will it work in? How can software architects, developers and clients benefit from using this design pattern? I will also try to discuss and present major advantages of this highly maintainable architecture.
Go to:
- 1. A consistent approach to software design is key
- 2. Architecture versus technology debt
- 3. What is a Clean Architecture solution?
- 4. Principles of Clean Architecture
- 5. Clean Architecture – design patterns
- 6. Disadvantages of Clean Architecture
- 7. Advantages of Clean Architecture
- 8. Which projects should I use Clean Architecture in?
A consistent approach to software design is key
When starting a new project, software engineers usually want to complete their first task very quickly, overlooking the importance of preparing the design. This is a mistake! After all, it is the initial stage of new application development that is the most important. It allows you to work out a consistent, fixed approach that will be used by other programmers involved in the project.
Architecture versus technology debt
Another mistake that developers often make is causing technological debt. It is true that we often create something quickly, which seems to make sense…
However, due to various factors, we incur more and more technological debt. When working on projects, taking shortcuts doesn’t pay. Haste and negligence are the most common reasons for technological debt!
It is not so bad if we cause a debt that we can later “pay off”, that is, make corrections on time. It is worse if it leads to debt that exceeds our skills or goes beyond the project timeframe. Unpayable technological debt can lead to something we are all familiar with. This is perfectly illustrated by the image below:
Clean Architecture – Technological debt based on the example of Poland’s public debt
To avoid this problem, it is worth using some of the many patterns available for architectural design. My favorite approach, one which I use most often, is Clean Architecture.
What is a Clean Architecture solution?
Clean Architecture is an approach to application programming that involves separating the four main functional modules in a project.
These modules are:
- Application,
- Presentation,
- Domain,
- Data.
I will discuss each of them in detail. To start with, a few words about the main concept of the Clean Architecture approach.
Principles of Clean Architecture
In his book “Clean Architecture”, Robert C. Martin (“Uncle Bob”) defines the purpose of architecture as supporting the life cycle of a system. As he says:
“Good architecture makes a system easy to understand, easy to develop, easy to maintain and easy to implement. The ultimate goal is to minimize system lifecycle costs and maximize developer productivity.”
While creating the Clean Architecture approach, Martin aimed to work out a project structure with clearly separated responsibilities of different layers.
According to the Clean Architecture design principles, each layer should perform one task and be easily isolated from others. Another assumption is that a single piece of code could be shared between multiple environments. This would be done by bringing out two main modules independent of the technology in which we create the application: Presentation and Domain, and sharing them in other environments, adding only the Application and Data layers. These layers are closely linked to the environment in which we run the project. A good example would be writing business logic once and sharing it across iOS and Android mobile applications as well as web and desktop applications.
Also read:
Clean Architecture – design patterns
The presentation module can be implemented using a number of popular design patterns:
- Model View ViewModel (MVVM),
- Model View Presenter (MVP),
- Model View Intent (MVI),
- Model View Controller (MVC)
and many others. Each developer has their own preference when it comes to choosing a pattern, although each of them has advantages and disadvantages. For the purpose of describing this architecture, we will focus on the MVP approach, the one I personally prefer.
Application
The application layer has the strongest connection to technology, where we use the Clean Architecture approach. It provides the entire visual part of the project and reacts to the tasks provided by the presentation layer. This layer determines how the data will be displayed. It contains the display logic and informs the presentation layer of any actions performed by the user. It also handles the Presenter’s state maintenance mechanism and prepares all the necessary dependencies for its proper operation.
Presentation
The Presenter controls both the entire application and individual screens. It also reacts to individual actions performed by the user in the visual part (GUI). It is also here that the decision is made on how to handle given tasks or which part of the application to show to the user in turn. UseCases, described below, are the only way this module communicates with others. It is used, for example, to execute business logic or to retrieve specific data. In the MVP approach, each Presenter has an interface to communicate with the view. This communication only allows tasks to be delegated to the view, but it does not allow something to be requested in return. Simply put, the Presenter executes functions on the visual interface, but these functions cannot have a return type.
Domain
Domain is the module that contains the business logic. It consists of a number of components:
UseCase
The most important, externally visible component. It is used by the presentation layer. UseCases are mappings of real business requirements that provide the presentation logic with access to data operations (fetch, change, listen for changes). They also allow business logic to be performed – calculations or manipulations – on data. It is worth mentioning that they are the only means of communication between the presentation layer and the domain layers. Data is transported by models stored in this layer as well. UseCases access data through DataSources via the interface they provide. The other type of dependencies they use are classes from the Logic layer described in the next parts of the article.
Model
This is a collection of data gathered in some logical way, used by business logic. This model does not have to be identical to the data layer model. It can, for example, combine several data models depending on the needs of the application.
Logic
A place in the structure that is used to store separated classes with extended business logic. This place makes it possible to avoid an extensive UseCase.
DataSource
The most important task of DataSources is to decide where data will be retrieved from or stored. DataSources, by means of interfaces, have access to all the data sources that the Data module exposes. In addition to the data inside, you will also find Mappers to translate the data from the Data layer into business models that will be used later. The DataSources are the only connection between the Data module and the rest of the business logic, and they are the ones that further expose the interfaces that give access to the customized data for the UseCase.
Mappers
The mappers in the Clean Architecture are responsible for the consistency of data provided by the Data layer. Here we check that all the necessary data has been provided so that the business logic can be fully operational. Mappers often combine several data layer objects from different sources to create one with all the data needed by business logic.
Data
A module that provides access to all types of data sources and models that map these data. The methods provided by this module can only be accessed via interfaces provided by this module. It is also the second module with the biggest dependence on the platform which Clean Architecture is used on.
Data transfer object
A data transfer object (DTO) is a model for two-way data transfer. Such models are only used in the Data layer, and depending on whether the data is being sent or retrieved, it is translated into or from business models using Mappers.
Data
Here data used in the rest of the application is retrieved and stored. Some examples of data sources are Bluetooth, Internet, Shared Preferences, databases, files, GPS, camera, gyroscopes or systems. Such data is accessed via the interface, which allows the source to be easily swapped. The substitution of such a source is done by specifying different objects implementing this interface. The substitution of data sources is most commonly used, for example, to support different types of servers or to support data mocking.
Disadvantages of Clean Architecture
Time-consuming
Implementing such complex architecture requires more time. In my experience, writing code using the Clean Architecture approach requires about 10% more time than developing an application without any special architecture.
You need know-how
There is a high entry threshold into this type of approach for people with no prior architectural experience.
A large number of small classes and interfaces
Some will see this as a disadvantage, and others quite the opposite. Suffice to say that there is a grain of truth in each opinion. In my view, it is an advantage – those with a different opinion find the number of files difficult to manage and the changes made to them unreadable.
Project team building. Get to know the practical tips for Scrum Teams.Read the article |
Advantages of Clean Architecture
Easier maintenance
Clean Architecture significantly simplifies project maintenance. Fixing and locating bugs with this approach is easier and faster.
Better change management
The approach speeds up the introduction of changes to the project. Thanks to small classes with separate responsibilities, it is very easy to modify the code for new requirements or add new functionalities without worrying about the impact on the rest of the project.
A large number of small classes and interfaces
As I have already written, there are myriad opinions on this topic. I consider it an advantage because, thanks to many small classes with separate functionalities, the code can be testable – that is, easily covered by tests.
Which projects should I use Clean Architecture in?
In my opinion, Clean Architecture works well in medium-sized to large projects. In small projects, the complexity of the approach may result in additional work.
But does this mean we shouldn’t use Clean Architecture in small projects? It’s worth remembering that they develop quickly and naturally. Deciding to use the CA approach even for smaller projects is justified, in my view. It allows you to avoid incurring the technological debt I mentioned in the opening paragraphs, especially when deadlines are not tight.
Summary
Referring to the concept of sharing two modules between multiple technologies, I think this is a great idea and we are getting closer to its application. So far it has been difficult to utilize its potential, but along with the development of programming languages like Kotlin, we may soon have the first projects that take full advantage of it. I hope I have been able to introduce the main principles of Clean Architecture and encourage you to use it in your projects. A well-considered choice of architecture will allow you to avoid technological debt, and this type of architecture – despite requiring detailed knowledge and allocating more time for implementation – undoubtedly works well in the long term in projects both large and small.
Go to:
- 1. A consistent approach to software design is key
- 2. Architecture versus technology debt
- 3. What is a Clean Architecture solution?
- 4. Principles of Clean Architecture
- 5. Clean Architecture – design patterns
- 6. Disadvantages of Clean Architecture
- 7. Advantages of Clean Architecture
- 8. Which projects should I use Clean Architecture in?