Layered Architecture in Android Overview
Architecture is a broad topic that can cover numerous different ideas and areas. One of the popular approaches on Android is a layered architecture, often inspired by "Clean Architecture". If you want to know more about "Clean Architecture" specifically, check out the original article by Robert C. Martin. This article will explain the three main layers of a standard layered architecture: Display (UI), Domain (Business), and Data (API/Persistence), and how they relate to one another.
The Domain Layer #
The best place to start is actually in the middle, because it is the layer that is not tied to the particular platform running the application. The Domain layer holds business logic, domain models (also known as entities), and data access interfaces usually in the form of repositories. The domain layer should not depend on any other layer, but any other layer may depend on the domain layer. This isolation allows the domain layer to stay agnostic of the platform and allow for near 100% test coverage. This is critical as the domain layer should hold crucial business rules in the form of Use Case classes that perform the core operations of the application.
The Data Layer #
The data layer is in charge of coordinating the data access and persistence. This includes logic for retrieving and storing data from a cache, api, or database. This layer is platform specific due to needing to know how to retrieve the data. It handles the specifics like using a Room database or an API with Retrofit. It also fulfills the contract for the data access repositories as defined by the domain layer. If there are models specific to the data layer they will be defined here but when fulfilling the repository contracts the model should be mapped to a domain model. However, if there is no difference between the data model and domain model, the domain model can be used in this layer.
The Display Layer #
The display layer is the user facing part of the application. In this layer all the logic for UI is held. On Android this would be the Fragments and XML or Compose views. Additionally, it might hold other user facing logic like notifications or audio playback. This is another layer that is platform dependent in order to display information to the user. This layer may utilize additional architecture patterns such as MVVM, MVI, etc to manage code related to rendering the UI. Similar to the data layer, the display layer may define display models if there are specific needs for the layer. Again however, if there is no difference between the ui and domain models, the domain model should be used to avoid unnecessary mapping work.
Moving Between Layers #
The final secret sauce that ties this whole architecture together is dependency inversion, usually accomplished using dependency injection. This article is not meant to explain dependency injection, but what needs to be understood is that using dependency injection to invert dependencies allows the layers to remain independent while providing specific implementations to make the app function. For example, the Domain Layer defines and uses a repository interface, but the repository implementation lives in the Data Layer. Using dependency injection, the implementation can be provided to the Domain Layer without requiring it to be dependent on the Data Layer.
Conclusion #
Isolating code into individual layers keeps it more organized and easier to read. Additionally due to the popularity of the basic layered architecture, navigating many Android code bases will be much easier with this knowledge. Try out this architecture in a project to see how much better it can make the codebase. Until next time, thanks!
Did you find this content helpful?
Please share this post and be sure to subscribe to the RSS feed to be notified of all future articles!
Want to go above and beyond? Help me out by sending me $1 on Ko-fi. It goes a long way in helping run this site and keeping it advertisement free. Thank you in advance!