Deep dive into Android Clean MVVM Architecture — Part I

Ali Shobeyri
Daresay
Published in
6 min readDec 1, 2022

About eight months ago, I pushed a project based on clean MVVM with Flow and TDD, but I never created an article to explain what I did there (although I had created a short diagram on GitHub) 😃

So here I am with complete documentation about that project; now you can learn how we can create an Android project based on Clean MVVM Arch 🎉

In the first part, I will explain the different aspects of Clean Architecture and MVVM, and in Part II, we will investigate one of the features of my project so you will read the theoretical issues and actual issues (code)!

We use Architecture to trace our codes and maintain them EZ PZ!

What is Clean Architecture?

When we are talking about Clean Arch, we simply mean separating your codes into individual modules with a specific task (we can say it’s related to the Single Responsibility Principle), but how can we achieve this?

Here we have a diagram of Uncle Bob’s article about Clean Architecture; as we can see, we have four different parts in a Clean Architecture project, and each level only is aware of the subset of itself; for example, “Use-Case” knows about Entity and doesn’t know anything about “Interface-Adapter” layer, ok let’s see what each of these layers is:

Entity

An independent framework part of your application that contains some basic logic of your code; for example, if we are in the Android project, the entity would be our pure model data without any dependencies from Android and some interfaces of repositories, etc. (we’ll create the implementation of those repositories in another layer), it must (should) be only based on Kotlin or Java (or whatever language you want) or in a nutshell “the core business logic/model of your App” so it can be re-usable for any other framework.

Use-Case

In simple words, “Actions/Events of your App” if you have a computer Eng background, you can recall what was UML, right? (if you don’t, UML is a bunch of Diagrams, I don’t want to make it hard 😄) on UML, we have something named “Use-Case,” and that’s the possibles actions of the user/system etc.

For instance, if we want to fetch a list of movies from the server, we have to create a Use-Case named “GetListOfMovieFromServer” use-cases don’t have to contain complex logic, and they are only a bridge from the Interface Adapters layer to the Framework layer.

Interface Adapters

Here we have all of our API and Repositories implementation and other things; here, we can trigger our Use-Cases and get data, then we can modify those data in a way we want and pass it to the Framework layer.

Frameworks

Well, it’s just Framework 🦾, like the Android SDK, Activities, Fragments, and other things, although we should keep our ViewModels in this section too.

And that’s it, now we with these four different layers, we can achieve to have a really good clean architecture, but how should we do this on Android?

Now look at this diagram :

Here is how data will be shown on the Framework layer, first “Framework” layer triggers a “Use-Case,” then that “Use-Case” will call a proper repository (or whatever) from the “Interface Adapter” layer, then the “Interface Adapter” layer is going to create a network request, and it knows what will be received from the server according to the “Entity” layer. After that “Interface Adapter” will modify that data and pass it to the “Framework” through the “Use-Case.”

And that is how good clean architecture works 🙌

Android Implementation Layers

There are lots of different ways to implement Clean Arch in Android, but I believe the best practice is this :

In the Android world, every feature should be a separate module, and it must have its own architecture, either clean or whatever. This way, if in further future we want to use another architecture, we won’t face any problems (I worked in a company where we met this issue, and it was a real pain 😭).

So we will have a “core” modules, which contains some basic modules and some utils classes, then we can have an “app” module which doesn’t have many responsibilities and it’s only a host for your features (it has a small number of duties), and we have “feature” modules which contains different features.

On every feature module, we will have three different sub-modules :

  • Domain: it contains the Entity layer and Use-case layer
  • Data: it includes the Interface Adapters layer
  • UI: it contains the Framework layer

One thing is missing here; if we have a clean architecture, where is MVVM here? The point is; Actually, you can use another MV* architecture or any other architecture within your clean architecture, for example in this case, “MVVM” is only for your “UI” layer 📱

Let’s talk about MVVM, too (if you know that, pass that section).

What is MVVM?

MVVM stands for Model, View, View-Model; it’s an architecture for lots of frameworks; View is your activity and fragments and other things, Model is your data and some utils for data, and View-Model is a replacement of Presenter on the older architecture (MVP), on MVVM we create a “stream of data.” The View can observe that stream of data, and with any changes, View can react and show different information to the user:

As you can see in this picture, View-Model doesn’t have any information about View (that’s why I showed it as a dashed line), and it doesn’t know how View reacts to the user on the older architecture MVP; there was no “stream of data,” we simply handled things with “call-backs,” if we use call-back we will have an Object A, and an Interface B (which is a call-back) then Object A must have an instance of Interface B (a concrete class of that interface) and either Concrete class B must have an instance of object A too. This is crazy! It will create conflicts and tracing code would be really hard (there is a term in programming called de-coupling, we always try to remove dependencies). But in MVVM, there is no instance of View in View-Model; View simply observes (or collects or subscribes or other terms) a stream of data of View-Model, and View-Model won’t do anything about passing data to View; it just triggers the stream of data and notifies that it is changed 👋

And that’s enough for this part! Let’s go for Part II and explore the feature “search” on the project.

Any comment? => s.shb.s.ali@gmail.com

Also, you can find me on LinkedIn: https://www.linkedin.com/in/iryebohs/

--

--