MVVM Clean Architecture Pattern in Android with Use Cases

Amit Raj
6 min readJun 26, 2023

--

Clean Architecture

MVVM (Model-View-ViewModel) is an architectural pattern primarily used in user interface development, particularly in frameworks like Android. It aims to separate the user interface (View) from the business logic (ViewModel) and data (Model). The ViewModel acts as an intermediary between the View and the Model, exposing data and commands that the View can bind to. This separation enables better testability, maintainability, and flexibility.

The objective is to separate the responsibility, make it testable, and avoid any strong dependencies on UI, frameworks, and databases. We could change a dependency smoothly without affecting the whole structure. we should follow the Separation of Concerns. It helps us to have an efficient application design by separating logic, data, and UI.

  • A reactive and layered architecture.
  • Unidirectional Data Flow (UDF) in all layers of the app.
  • A UI layer with state holders to manage the complexity of the UI.
  • Coroutines and flows.
  • Dependency injection best practices.

MVVM pattern

MVVM is a widely adopted design pattern in Android development, known for its ability to separate view and business logic. By applying Clean Code principles, developers can effectively segregate these concerns, resulting in a clean, robust, and easily maintainable project. However, one drawback of MVVM is that in larger projects, the View Model often becomes burdened with an excessive amount of business logic. In such scenarios, employing MVVM alongside Clean Code practices can prove invaluable, as it enables the separation of responsibilities, promotes project solidity, and facilitates effortless evolution and maintenance.

The project is divided into three layers:

  • Data
  • Domain
  • Presentation

Data Layer

As the name suggests, it contains our data. API interfaces, databases, and Repository Implementation reside in this layer.

The Data Layer in clean architecture assumes the role of handling data flow and retrieving information from diverse sources like databases, web services, and files. It further manages data persistence and facilitates data access. Additionally, the Data Layer serves as an interface for seamless interaction between the application’s other layers and the data. It acts as an abstraction layer, shielding the data from direct interaction with the rest of the application.

Domain Layer

Our models (entities containing data) and Repository interfaces are included in this layer. At the same time, the business logic of the project is kept in this layer along with the Use cases

The domain layer serves as the hub for business logic, encompassing tasks such as data conversion, filtering, merging, and sorting. Its purpose is to transform the raw data received from the data layer into a processed format that is convenient and manageable for the presentation layer to handle.

Presentation Layer

The presentation layer serves as the interface between the user and the application, handling user input and displaying the corresponding outcomes. This layer usually consists of a graphical user interface, like a web page, mobile app, or desktop application. In the MVVM architecture, the presentation layer comprises view and view model objects. Views, represented by Activities or Fragments, should strive to remain simple and devoid of business logic. If any business logic exists within the views, it becomes essential to refactor these classes accordingly.

Let’s explore the practical applications of MVVM Clean Architecture.

In Android development, we have the option to adopt the MVVM (Model-View-ViewModel) pattern, where the ViewModel class takes charge of managing UI data while being mindful of lifecycle events.

  • The View managers (Activities, Fragments) should not contain any other logic than view logic (showing/hiding elements, component click listeners, etc). They observe the data from the ViewModel and change the components accordingly.
  • The ViewModel is the entry point of the data access layer. It is used to interact with the Model and bound to the View.
  • The Model is any class relating to the data access layer, either domain data models.

UI: Managers of the view components, observe the changes from the ViewModels and update the UI components.

ViewModels: These controllers are the entry point of the Android Framework. They collect the data by launching and starting the flows. The VMs are responsible for the flow lifecycle.

UseCases: They are the reflection of user interactions. Each use case is an action. They use the Repository flows and defined the application logic.
Within the MVVM structure, the ViewModel classes typically encompass all operations. However, as the application grows, the increasing number of ViewModel classes can lead to scattered business logic and redundancy. To mitigate this complexity, a solution is to introduce various UseCase classes. These UseCase classes help alleviate the burden on ViewModel classes by reducing code duplication and overall complexity.
Advantages of Using Use Cases

  1. Reusable.

For example, we can use a Use case we created for GetUserProfile on all Profile-related screens.

2. Eliminates code duplication(Boilerplate code)

For example, if we didn’t have Use Cases and put all the business logic inside the ViewModel and we had 2 View Models that needed to access the same data, we would have the same code in both View Models. On the other hand, if we have a Use Case and put the code we mentioned in Use Case, we can call this Use Case class in both ViewModels and use it.

3. It leads to Screaming Architecture.

This means that when we look at the use-case classes, we can understand what the project is really about since we have the project’s “feature” packages in it. For example, if we examine the Use cases we have created for the Profile screen, we will have information about what the user can and cannot do on the Profile screen.

4. It simplifies the View Model

While Use Case does the job, ViewModel updates LiveData based on information returned by Use Case. Thus, the ViewModel now has less workload, so the View Model is simplified.

5. It reduces the project’s dependency on the View Model.

Use Cases access Repository while ViewModel can only access Use Cases. That is, ViewModel has no direct access to Repository when we use Use Case.

Repositories: They apply the business logic to the Service flows.
In MVVM architecture, the repository plays a crucial role as an intermediary between the data layer and the rest of the application. The primary purpose of the repository is to abstract the data source implementation details and provide a clean and consistent interface for accessing data.

The repository acts as a single source of truth for fetching and storing data. It handles data retrieval from various sources such as databases, web services, or local files, and also manages data caching and synchronization.

By using a repository in MVVM, several benefits can be achieved. It promotes separation of concerns by isolating data operations, allowing the ViewModel to focus on business logic and the View to concentrate on rendering and user interactions

Overall, the repository acts as a bridge between the data layer and the rest of the application, providing a centralized and standardized way to access and manage data in an MVVM architecture.

Result

I appreciate your readership and the opportunity to discuss important architectural concepts such as Clean Architecture, MVVM, and the UseCase structure. While I aimed to provide a concise overview rather than delving into extensive details, my intention was to give readers a general understanding and encourage them to gain practical experience by implementing the UseCase structure in their own code. I hope that this approach proves valuable to them.

--

--