Table of Contents

In software engineering, a design pattern is a commonly occurring problem in software design. A design pattern is not a final design that can be transformed directly into solved code.

One major problem in software development is the tight coupling of code, i.e. even a small change in one portion of code results in modification or bugs in some other part of code. Code is not unit test friendly, and code is not reusable.

Introduction

Currently, many architectural approaches are available like MVP, FLUX, MVI, MVVM that are solving the above problems. We can use any approach to maintain our code correctly so that everything works well, in short, a happy developer life. This article discusses the MVVM design pattern in android and how we can solve existing problems with the MVVM design pattern.

The main component in the MVVM design pattern are :

  1. View - Informs the ViewModel about the user’s actions
  2. ViewModel - Exposes streams of data relevant to the View
  3. DataModel - Abstracts the data source. The ViewModel works with the DataModel to get and save the data.

Brief Explanation of MVVM Design Pattern

Google introduced Android Architecture Components, which included ViewModel rather than Presenter and hence the proof that even Google is supporting MVVM.

ViewModel

ViewModels are simple classes that interact with the logic/model layer and expose states/data and have no idea by whom or how that data will be consumed. Only View(Activity) references ViewModel and not vice versa; this solves our tight coupling issue. A single view can have a reference to multiple ViewModels.

➡️
public class MainViewModel extends ViewModel {public MainViewModel() {}public String getText() {return new DataModel().getText();}}View

In Android, activity represents a view in MVVM design pattern. The View is responsible for the visual display of applications and data input by users. This part should not process the data under any circumstances. Its function is only to detect the input like touch or swipe and visualization.

The ModelView-ViewModel architectural pattern was introduced to Android with the birth of the DataBinding library. You can enable data-binding from the app.gradle.

➡️
dataBinding{enabled = true}

Add these lines in-app.Gradle inside android{} tag. Then put your XML layout code under tag. This will generate a binding class, and you can access this class from the activity. You can see we can directly access the getText() method from XML.

➡️
<?xml version="1.0" encoding="utf-8"?><layout><data><variablename="mainViewModel"type="com.g.mvvmproject.MainViewModel" /></data><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@{mainViewModel.text}"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent" /></RelativeLayout></layout>

After setContentView inactivity you set a reference of the view model.

➡️
public class MainActivity extends AppCompatActivity {private ActivityMainBinding mActivityMainBinding;private MainViewModel mainViewModel;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);mActivityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);mainViewModel = new MainViewModel();mActivityMainBinding.setMainViewModel(mainViewModel);}}

DataModel

DataModel holds the data of the application. It cannot directly talk to the View. Generally, it’s recommended to expose the data to the ViewModel through Observables.

➡️
public class DataModel {String text="Hello World ";public String getText() {return text + text;}}

Advantages of using MVVM Design Pattern

  • Your code testability is increased.

In the below code snippet, we test the getText() method in ViewModel. You can mock your data and check the expected result.

➡️
@RunWith(AndroidJUnit4.class)public class ExampleInstrumentedTest {@Testpublic void emailValidator_CorrectEmailSimple_ReturnsTrue() {String expected = "Hello World Hello World ";assertEquals(expected, new MainViewModel().getText());}}
  • Your code is decoupled.
  • The package structure is even easier to navigate.
  • The project is even easier to maintain.
  • Your team can add new features even more quickly.

Conclusion

MVVM combines the advantages of separation of concerns provided by MVP while leveraging the advantages of data bindings. The result is a pattern where the model drives as many operations as possible, minimizing the logic in the view.

➡️
A simple example of the MVVM implementation can be found here.

Srinivasa Sainath

Srinivasa Sainath