The only way to make the deadline—the only way to go fast—is to keep the code as clean as possible at all times.

– Robert C. Martin, Clean Code: A Handbook of Agile Software Craftsmanship

Introduction to Architecture Patterns

Since the beginning of humanity, people have tried to develop techniques to reduce efforts in every task. And that is the main reason for this rapidly evolving era. We want things to be done easily and quickly with less amount of efforts.

The case is no longer different for the Developers Community. Every developer wants their programs to be created and managed easily. For that, we need a specific managed way of development, which we call – Architecture Pattern.

We need a proper architecture pattern to develop a software because…

  • It makes code easy to understand and manageable. You define specific roles to different layers of responsibilities. The entire app components are created in such a way that modifying one layer will not directly harm the other layers of the code.
  • The core business logic of the app becomes easily testable.
  • The complexity of the development increases as the project becomes larger. If you don’t follow any pattern, it is possible that you end up in a complex maze with no way out.
  • If you are following an architecture pattern, you’ll never feel annoyed if the client changes the requirements frequently.

Architecture Patterns in Android

The smart developers of the world have devised various architecture patterns which we can follow while developing apps for Android. Some of them are…

  • MVC – Model View Controller
    • Models refer to data sources for which we create POJO classes most of the times.
    • Views refer to layout files in XML.
    • Controllers refer to Activity/Fragment classes which are responsible for retrieving data from Models (and updating data of Models) and displaying the data into Views.
  • MVP – Model View Presenter
    • Models have the same role as in MVC.
    • Here, Views refer to Activity/Fragment classes + layout files.
    • The role of Presenter is similar to the role of Controller in MVC, but the presenter is not bound to any view directly and does only contain business logic. UI updation is done by Views when Presenter notifies View with data.
  • MVVM – Model View ViewModel
    • Models have the same role as in MVC & MVP.
    • Here, Views refer to Activity/Fragment classes + layout files. Views observe on data being updated by ViewModel in such a way that, if the value of variable changes in the ViewModel, the View automatically reflects the changes with the updated value.
    • ViewModels are responsible for getting and updating data from Models and to provide Observable data which can be observed by Views.

 Getting Started with MVVM

 

Flow of MVVM

You may have noticed that MVC pattern is what we are following unknowingly till now. There are some limitations in MVC and MVP:

  • In MVC, the business logic and UI updation logic resides in the controller. So, the testing of business logic would not be easy without running app.
  • In MVP, Presenters are indirectly bound to views via interfaces. For larger projects, it would not be easy to work with a large number of interfaces for each view.

As we know that Android app may go through any of the lifecycle methods in its lifetime. But switching between lifecycle methods should not affect the user experience at any cost.

For Example, you are loading a list of images from the remote server into RecyclerView of an app. But due to slow internet connectivity, the images took 1 minute to load. Now user rotates the phone, the activity gets recreated, the RecyclerView loads again the images and user needs to wait again. This is a bad user experience. Configuration changes lead the activity to recreate, but this should not break the continuity of user engagement.

To address these issues, MVVM has come into the picture.

MVVM is used to decouple the responsibilities of the app into different layers. Imagine that if you are loading data from web service and you are told to load data from the local database instead. It would take a lot of time and effort if you have not decoupled the responsibilities into different layers. But with MVVM, you could change data sources easily.

MVVM was introduced for Android after the DataBinding library was released. With the reactive behaviour of DataBinding, the View can observe changes in ViewModel and update accordingly. It is recommended that you understand few concepts of DataBinding before proceeding.

The layout file with data binding looks like this:

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <!--the name and type viewModel defined here. -->
    <data>
        <variable name="viewModel" type="com.demo.viewmodel.DemoViewModel" />
    </data>

    <LinearLayout...>
          
            <TextView
                ...
                android:text='@{viewModel.name}' />
            <TextView
                ...
                android:text='@{viewModel.email}' />
            ...
           
    </LinearLayout>
</layout>

We defined variable of DemoViewModel in <data> element of XML. There are two TextViews which are observing the data variables of ViewModel – name and email.

DemoViewModel.java file looks like this:

public class DemoViewModel extends BaseObservable {

    private User mUser = new User();

    public DemoViewModel(){
       ...
       // load data from any data source into user (web service or local data)
    }


    @Bindable
    public String getName(){
       return (mUser != null) ? mUser.getUserName(): "";
    }

    @Bindable
    public String getEmail(){
        return (mUser != null) ? mUser.getUserEmail(): "";
    }

    public void setName(String name){
        mUser.setUserName(name);
        notifyPropertyChanged(BR.name);

    }

    public void setEmail(String email){
        mUser.setUserEmail(email);
        notifyPropertyChanged(BR.email);
    }

}

Here, we have extended DemoViewModel from BaseObeservable class which provides functionality to create Observable fields. Generally, the observable property defined in XML files (name and email) are bound to Observable methods with the following convention: “get + PropertyName” in camel case (getName and getEmail). We annotate Observable methods by @Bindable.

notifyPropertyChanged(BR.propertyName) method is used to notify changes to Observable data. The UI components which are observing these properties are automatically updated with new data upon this method call.

To bind ViewModel to the View, we write following code in the Activity:

ActivityMainBinding mActivityMainBinding;
   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       mActivityMainBinding = DataBindingUtil.setContentView(this,R.layout.activity_main);
       mActivityMainBinding.setViewModel(new DemoViewModel());
   }

Advantages of MVVM

  1. Provides clearer separation of the UI and business logic.
  2. Unit testing becomes easier, as there is no dependency on the core components of Android.
  3. Persists through the configuration changes of Activity.

Disadvantages of MVVM

  1. Databinding errors require practice to understand.
  2. For small applications, using MVVM adds unnecessary overhead.

Conclusion

So, after reading this post, I’m sure you’ll try it once in your project. MVVM has really become the choice of hardcore developers.

There is one more interesting thing that you should be knowing:

Google has recently launched Architecture Components for Android which include: ViewModel, LiveData, Room, and LifeCycle. You should try it out as they make MVVM even easier.

I hope the upcoming year of 2018 will go smoothly for you with the use of MVVM.

Happy Coding!

Want to work with us? We're hiring!