Clean Architecture + Redux + Android

Have been learning a new tricks in mobile architecture on the native side.

Applying the redux pattern to android architecture components and MVVM has been interesting.

I have written some brief overviews of such things - if talk is cheap and just want the code - check out namegame or jokeapp.

Jetpack Compose

Android compose is a modern declarative toolkit for building user interfaces.

Inputs to compose functions become important in determining whether the UI should re-compose.

You can remember values for re-composing, but the state is the function parameters.

The ability to control which functions re-render is in-line with virtual doms of react-native.

Less code, simpler, easier to maintain (reminds me of a functional more efficient Java Mobile Edition)

Kotlin Flow

Kotlin flow borrows from Reactive extensions and Golang channels to allow observable streams that produce and consume state.

This works well with compose in that state produced from a kotlin flow can trigger a compose function to recompose.

  val state by viewModel.stateFlow()
  Screen(state)

Clean Architecture

Clean architecture from uncle bob has been around a while and defines principles for low complexity maintable code.

The principles are known as the SOLID acronym. They were somewhat intuitive and may have already been practicing them, but its nice there is a formal definition.

To promote the use of these principles it is helpful to layer a code base (typically data, domain and ui).

For example when sending data from the data layer to the ui layer, it becomes necessary to define an interface for it which is the Dependency inversion principle.

Redux / Flux / Composable

The overview says “redux is a pattern for managing application state using events”.

Flux uses multiple stores and makes more use of a dispatcher where redux provides a single store, reducers, and immutability.

Keeping state immutable is important when complexity grows, to eliminate the possibility of modules modifying your state outside of scope.

Thinking of clean architecture, the redux pattern follows the Single Responsibility principle. Perhaps a bit more cohesive to me than similar architectures (MVI).

I betray the single store principle of redux on Android, as they recommend keeping state in scope of a view model.

Store and Reducers

A brief intro to redux if you have never used:

Modifying immutable state is done by passing state through reducers to return a new state.

The store publishes and subscribes to events and maintains state from reducers.

Action

Actions are events that hook into the application, such as user interface, and dispatched to the store.

onClick={ dispatch(ViewAction.ButtonClicked) }

Middleware or Effects

The store sometimes has middleware that performs effects on actions that do not return a new state.

In the web world, this is middleware, in the mobile world, this seems to be called “effects” (composable architecture).

Summary

The unidirectional immutable data flow of redux and clean architecture allows maintainable reliable code.

Combined with subscribable state flows, coroutines and jetpack compose ui, it opens many doors to very sophisticated user experiences without the fuss.

References