Klean Kotlin - How Kotlin Can Enhance Clean Architecture

Posted: 06 Mar 2018. Last modified on 27-May-22.

This article will take about 4 minutes to read.


Clean Architecure

Devised by Robert Martin, the author of “Principles of Object Oriented Design”, which gave us SOLID

Clean architecture is a way of separating concerns so that business logic is unaffected by our choice of technoliges. Using this style of programming, changing databases, UI frameworks, or even platforms becomes a much more manageable task.

Specifically, the goal of clean architecture is to make your application’s business logic:

  1. Independent of Framworks
  2. Testable
  3. Independent of UI
  4. Independent of Databases
  5. Independent of any external libraries or logic

1 2 3 4 5 6

The VIPER Architecture:

Th View is usually a Fragment, it is the only element which cares about android lifecycle changes.

It has a reference to the Presenter and the Router

The Presenter is in charge of manipulating the view based on the information in the interactor. It has a reference to the Interactor and the View.

The Interactor holds the business logic for the application. It holds methods which can be called in response to other events happening in the ViperStack, like UI elements or the reeipt of a set of datamodels from the Repository. It holds a reference to the Router, Repository, and Tracker.

The Respository is used to gather data from various data sources and translate them int odatamodels which can be passed to the Interactor and displayed via ViewModels in the Presenter. It holds a reference to the Interacotr and the Tracker.

The Router is used to change between differnet screens. It allows us to move between fragments, activities and dialogs. It holds a reference to the Tracker and is able to obtain an instance of Activity.

The Tracker is used to make tracking calls. This class is separated from the rest of the business logic in the interactor because tracking should not affect the use cases that the interactor is attempting to codify.

Applying Kotlin

Non-nullability

Nullability is unavoidable in Android, due to the way that the framework is set up.

Kotlin allows us to limit that nullability.

Using a clean architecture, we can confie nullability to the outer layers of the application, so that our bisuness logic can assume that it is always operating on valid data.

The inner layer should alwys be protected from outside changes.

Datamodels

Datamodels, which hold information which has been generated by Repositories, are a great use case for data classes. Data classes can help us out in a lot of ways when we apply them to datamodels.

Using Kotlin’s apply() standard function, we can create complex data structures that let us keep the instantiation code readable.

var obj = LargeObject().apply {
    name = "LargeObject"
    type = 22
    properties = Properties().apply {
        value = 123
    }
}

Repositories

since we know that the server can give us null values, we can use the repositories as a filter.

The repository’s main job is to create datamodels based on the data that we get from databases or network requires, so we can fill in default values in the repository to keep the contes of generated datamodels non-nullable.

Presenter

It’s easy to miss a nullcheck in the presenter. The View could be set to null on rotation, but explicitly checking everywhere adds a lot of boilerplate code.

Using kotlin, we can ensure that we will not get an NPE if the view no longer exists, with safe calls.

This lets us worry more about what we are trying to present, and less on if we should be presenting it.

Interactor

Functional programming allows for more flexibility.

Functional languages are good when

Using lambdas allows for much less boilerplate

The flexibility of kotlin allows us to describe what is happening in a more natural way, by grouping together steps in a use case instead of having to worry about the state of the application.