The Clean Architecture
This sample project is inspired on The Clean Architecture by Uncle Bob.
Its main goal is to follow the SOLID principles in order to keep the software well organised, testable, easy to maintain and more importantly easy to extend/change.
As explained in the posts above and in the book, databases, network clients and frameworks are abstracted in the upper layers (Entities, Data and Domain layers) and should not be imported/referenced into them, instead they should be injected in the App level as dependencies through the interfaces exposed by the upper layers.
In this sample app we have the following modules/layers:
Framework responsible for linking the Interfaces to the
Factories. This should only the referenced/used in the
Top level module. This should not have access to any other module in the system and must be the simplest possible.
Responsible for exposing a few Interfaces for external plugins implementations such as databases, memory caches, network, bluetooth, etc. This should not reference any concrete class related to these. It also contains the
Repositories which are another abstraction for the use of the plugins mentioned above. This module can only access
Entities layer, nothing else.
This module exposes
UseCases to process business logic using the Command Pattern. The use cases must be simple and have only one responsibility. They usually communicate with
Repositories from the
Data layer through Interfaces. Ideally
UseCases would return
DataStructures instead of
Entities to the lower layers, since these could contain UI-specific data which isn't part of the
In this layer we have all the code that's specific to the platform of development. In this sample project the platform is iOS, furthermore a concrete implementation of the
CacheInterface exposed by the
Data layer was implemented in the
App layer using
UserDefaults as the persistence choice, for example.
This layer may have
Views, third party frameworks and, finally, is also responsible for setting up the dependency graph for the project by linking all the interfaces to their respective concrete classes.
Even though I haven't written any tests yet, the whole project is completely testable, since all layers are being isolated by interfaces, as suggested by the SOLID principles.