Table of contents
The essence of Clean Architecture is selecting an architecture and coding methods for systems that reduce the costs of their creation, operation, development, and modernization throughout their entire lifecycle. This minimizes the total cost of ownership of a system while simultaneously maximizing the productivity of the development team. Robert C. Martin, the creator of the Clean Architecture concept, once wrote that “any organization that designs a system will inevitably produce a design whose structure is a copy of the organization’s communication structure”[i]. There is a lot of truth in this statement – diligence in design and coding is closely linked to the organizational culture of the entire company. Correct choices at the design stage and high-quality work by developers ensure that the code is easy to understand, develop, and maintain, and that the deployment itself proceeds quickly and smoothly.
What exactly is Clean Architecture?
At the foundation of Clean Architecture lies the assumption that formulated business requirements should have minimal connection to specific technology and implementation details. Therefore, all layers forming the project structure should have clearly defined tasks and responsibilities, while being easily isolatable from the solution as a whole. Going further, Robert C. Martin proposed designing systems so that as much code as possible can be shared across multiple environments. In his original proposal, four layers could be distinguished:- application,
- presentation
- domain/business logic
Clean architecture – key concepts
Clean architecture can be visualized as concentric circles corresponding to individual architectural layers, with the highest-level layer in the center. Thus, at the center, we have domain logic and entities, i.e., business objects. It is worth remembering that domain logic, or in a slightly narrower sense – business logic[iv], concerns rules functioning in a given area of human activity. Such invariants function regardless of whether any software using this logic has been created. An example could be calculating income tax or the process of tracking a shipment to a customer. All significant business processes and workflows must also be reflected in this layer. The components of the domain logic layer include:- UseCase – a component whose task is to map true and real business requirements and provide the presentation layer with access to data operations – e.g., retrieving or modifying values through calculations. Interestingly, UseCase is the only way to exchange data between the presentation layer and the domain logic layer.
- Model – a collection of data organized according to selected rules, which are used by business logic. Models in this layer can differ significantly from models in the data layer, e.g., by combining several models into one, depending on needs.
- Logic – a place in the structure used to store isolated classes describing complex cases of domain logic that are used less frequently. This avoids overly complex UseCases.
- DataSource – these decide where data is retrieved and saved and have access to all data sources provided by the data layer. They are therefore the only connection between the domain logic and data layers. The task of the DataSource is to prepare data for processing in the UseCase.
- Mappers – ensure the consistency and completeness of data provided by the data layer so that the domain logic can function flawlessly. Mappers often integrate several objects from different sources in the data layer to create one object that contains all the data necessary from the perspective of domain logic.
- Data Transfer Object (DTO), i.e., a model for bidirectional data transfer. They are used only in this layer, and their services are used by mappers or business models, depending on the direction of data transfer.
- Data – these are places for retrieving and saving data used in other modules of the system. Appropriate interfaces allow for easy and fast replacement of data sources – it is enough to provide appropriate objects implementing these interfaces to replace data arriving via Bluetooth with a stream of data from the internet, a GPS system, or a camera. Such replacement of data sources is most often used when handling different types of servers or using test data.
