Integrate API Test Suite in AWS CodePipeline

If you are building an automated test scripts and want to get started in knowing how to integrate your test suite in CI/CD process then this is a beginner guide for you. Here I am going to illustrate…

Smartphone

独家优惠奖金 100% 高达 1 BTC + 180 免费旋转




Create Android apps using MVVM with Clean Architecture

Why Architecture Is Important

All architectures have one common goal — to manage the complexity of your application. You may not need to worry about it on a smaller project, but it becomes a lifesaver on larger ones.

How does Clean Architecture approach the problem?

First we’ll see what it looks like:

Additional benefits of using an architecture when structuring app code include:

Five design principles make software design more understandable, flexible and maintainable. Those principles are:

Cone view of Clean Architecture-

Clean Architecture maximizes the use of these principles.

MVVM separates your view (i.e. Activitys and Fragments) from your business logic. MVVM is enough for small projects, but when your codebase becomes huge, your ViewModels start bloating. Separating responsibilities becomes hard.

MVVM with Clean Architecture is pretty good in such cases. It goes one step further in separating the responsibilities of your code base. It clearly abstracts the logic of the actions that can be performed in your app.

Our data flow diagram:

The code is divided into three separate layers:

We’ll get into more detail about each layer below. For now, our resulting package structure looks like this:

Even within the Android app architecture we’re using, there are many ways to structure your file/folder hierarchy. I like to group project files based on features. I find it neat and concise. You are free to choose whatever project structure suits you.

This includes our Activitys, Fragments, and ViewModels. An Activity should be as dumb as possible. Never put your business logic in Activitys.

An Activity will talk to a ViewModel and a ViewModel will talk to the domain layer to perform actions. A ViewModel never talks to the data layer directly.

Here we are passing a UseCaseHandler and two UseCases to our ViewModel. We’ll get into that in more detail soon, but in this architecture, a UseCase is an action that defines how a ViewModel interacts with the data layer.

The domain layer contains all the use cases of your application. In this example, we have UseCase, an abstract class. All our UseCases will extend this class.

And UseCaseHandler handles execution of a UseCase. We should never block the UI when we fetch data from the database or our remote server. This is the place where we decide to execute our UseCase on a background thread and receive the response on the main thread.

As its name implies, the GetPosts UseCase is responsible for getting all posts of a user.

The purpose of the UseCases is to be a mediator between your ViewModels and Repositorys.

Let’s say in the future you decide to add an “edit post” feature. All you have to do is add a new EditPost UseCase and all its code will be completely separate and decoupled from other UseCases. We’ve all seen it many times: New features are introduced and they inadvertently break something in preexisting code. Creating a separate UseCase helps immensely in avoiding that.

Of course, you can’t eliminate that possibility 100 percent, but you sure can minimize it. This is what separates Clean Architecture from other patterns: The code is so decoupled that you can treat every layer as a black box.

This has all the repositories which the domain layer can use. This layer exposes a data source API to outside classes:

PostDataRepository implements PostDataSource. It decides whether we fetch data from a local database or a remote server.

The code is mostly self-explanatory. This class has two variables, localDataSource and remoteDataSource. Their type is PostDataSource, so we don’t care how they are actually implemented under the hood.

In my personal experience, this architecture has proved to be invaluable. In one of my apps, I started with Firebase on the back end which is great for quickly building your app. I knew eventually I’d have to shift to my own server.

When I did, all I had to do was change the implementation in RemoteDataSource. I didn’t have to touch any other class even after such a huge change. That is the advantage of decoupled code. Changing any given class shouldn’t affect other parts of your code.

Some of the extra classes we have are:

UseCaseThreadPoolScheduler is responsible for executing tasks asynchronously using ThreadPoolExecuter.

This is our ViewModelFactory. You have to create this to pass arguments in your ViewModel constructor.

I’ll explain dependency injection with an example. If you look at our PostDataRepositoryclass, it has two dependencies, LocalDataSource and RemoteDataSource. We use the Injection class to provide these dependencies to the PostDataRepository class.

Injecting dependency has two main advantages. One is that you get to control the instantiation of objects from a central place instead of spreading it across the whole codebase. Another is that this will help us write unit tests for PostDataRepositorybecause now we can just pass mocked versions of LocalDataSource and RemoteDataSource to the PostDataRepository constructor instead of actual values.

Note: I prefer using Dagger 2 for dependency injection in complex projects. But with its extremely steep learning curve, it’s beyond the scope of this article. So if you’re interested in going deeper, I highly recommend Hari Vignesh Jayapalan’s introduction to Dagger 2.

See you in the next tutorial, but for the time being I bid adieu :)

Add a comment

Related posts:

Silent Joy

I have pondered the Pali terms Piti and Sukha lately. They are the first two constituents of the First Jhana. The Jhanas are states of peace and/or of absorption encountered in Buddhist meditation…

Deep Learning With React Native

There has always been a huge amount of excitement around topics like Artificial Intelligence(AI). When someone mentions AI, you either think about AIs like Siri and how our lives have changed over…

Tacuma Ogunseye as a Scapegoat

Tacuma Ogunseye recently surrendered to the police in Guyana. He is being accused of violating section 2 (3) of the Racial Hostility Act. I have expressed in prior articles that I did not agree with…