Code Reusability – ViewModels and RxJava

TLDR; Think about how the code you are writing today can be reused. Will this exact code being used in another project or module, or is there a boilerplate pattern? If so, write some helper functions and classes.

Code reusability and organization is an obvious concern to always think about, so I won’t go into the details here. However, it’s not always clear when it is the right time to abstract away code that may be used multiple times. Should we wait until the code is about to be used multiple times? Or should the code be abstracted and organized as soon as we write its original usage? How do we even know if what we are writing can be expressed in a re-usable way?

In order to avoid technical debt, I always like to consider the following questions whenever I am about to write a piece of code:

  • Am I going to use this exact piece of code multiple times through this project, or across multiple projects?
  • Even though the code may be entirely specific to a piece of your application, does it have a lot of boilerplate code within?

If either of these bullets are true, I immediately think about how to write this code in a reusable way.

A great example of this comes from my good friend Elijah Stiles regarding Android ViewModels and Reactive Streams. When using an Android ViewModels with RxJava, you know that each ViewModel is very specific to the business logic for part of your application, but there is still a lot of reusable boilerplate concepts that can be abstracted away – disposing of Observables, setting threads to subscribe on, registering on a specific Android lifecycle, etc… By building a few helper methods within a base class which all ViewModels can extend, not only do you organize your code, but you reduce a ton of mental load when writing code later in your application. In the example below, we never really have to worry about disposing of our reactive streams – we simply wrap our streams with disposeOnCleared.

import androidx.lifecycle.ViewModel
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.disposables.Disposable

/** Base view model class used for making common functionality easier. */
abstract class BaseViewModel : ViewModel() {
    private val compositeDisposable = CompositeDisposable()

    override fun onCleared() {
        compositeDisposable.dispose()
    }

    /** Disposes of the given disposable when the view model is cleared. */
    fun disposeOnCleared(disposable: Disposable?) {
        disposable ?: return
        compositeDisposable.add(disposable)
    }
}

We no longer need to maintain pointers to our disposables within our ViewModels – the CompositeDisposable handles everything for us, giving us the freedom to write the logic that matters.