Android Architectures: MVI vs. Viper

Posted: 12 Jul 2021. Last modified on 27-May-22.

This article will take about 4 minutes to read.


The State Problem

Stateful code can cause subtle problems, especially on large teams.

It’s hard to reason about things which can change while we are reasoning about them. 1

If the data is immutable you need to know:

  1. what it means,
  2. where it was first assigned,
  3. and how it is used here.

If the data is mutable you need to know

  1. what it means,
  2. where it was first assigned,
  3. where it can be changed,
  4. when it can be changed,
  5. if those changes can happen concurrently and require locks,
  6. what sequence those locks need to be acquired in,
  7. if changing the data needs coordination with other teams,
  8. if it has been changed before,
  9. and how it is used here.

There is much more to keep track of! Concurrency is another reason why immutable data structures are great.

MVI

While MVI stands for Model, View, Intent, I prefer to call it Model, View, Intention to decrese confusion when talking about it in an Android context (Intent is a common Android class).

Before talking about that MVI is, it is worth it to discuss the alternatives.

MVC, MVP, MVVM

All of these architectures serve a common purpose:

It takes a lot of effort to bring an entire team on board with an architecture. If we are happy with our codebase and its test coverage, why do we need to try a new architecture?

MVI can be applied on top of existing patterns.

We don’t have to change the style that we’ve already adopted

Some things that you can do to work towards a more MVI architecture:

Pros of MVI

It’s functional!

It can be easy to add new user actions and components

Reactive programming allows for cleaner, less verbose code

Reduced coupling allows for tons of code reuse

Cons of MVI

It’s heavily dependent on Rx

There are lots of small objects being generated and thrown around

Changes and modifications may take more time than when done impreatively

Pure MVI

How does this measure up against an architecture like VIPER?

VIPER is attempting to do the same thing in a very similar way.

One common deviation that MVI takes is the concept of a reducer.

Reducers take in

Reducers can keep a reference to the previous State, so that unchanged values can be passed along to the new State.

Keeping all of the State of a screen in one place is a good idea for simple screens, but it’s harder to maintain in an invironment where each view can have its own DataModel.

See also:

DroidconNYC 2017 - TODO MVI implementation Facebook’s flux architecture