Clean Code in Kotlin – Coding N Concepts

0
34

In this post, we’ll learn how to write clean code in Kotlin with some practical examples and make our code more concise and readable

Use when

Use when expression, when you have more than two conditions. You can replace any code snippet having if-else condition with more concise when expression. It is similar to switch operator in Java.

// Don't
fun getCategoryByEatableName(eatable: String): String 

// Do
fun getCategoryByEatableName(eatable: String) =
    when(eatable) 
        "mango", "banana", "apple" -> "FRUIT"
        "potato", "tomato", "onion" -> "VEGETABLE"
        "milk", "curd" -> "DAIRY"
        else -> "UNKNOWN"
    

Use also

The also function does not mutate the returned output from the previous function and it comes handy in printing the output for debugging.

Example 1

We want to multiply and print the returned output, which make our method verbose like this: –

fun multiplyAndPrint(a: Int, b: Int): Int 
    val c = a * b
    println(c)
    return c


var out = multiplyAndPrint(2, 3)
// out = 6

Let’s improve above function where multiply only do the multiplication and also take care of printing the returned output

fun multiply(a: Int, b: Int) = a*b

var out = multiply(2, 3).also  println(it)
// out 6

Even if you call another function add from also expression, it does not mutate the returned output of multiply

fun multiply(a: Int, b: Int) = a*b
fun add(a: Int, b: Int) = a+b

var out = multiply(2, 3).also  add(it, 4)
// out is still 6, not 10
Example 2

The also function is quite useful in the streams as well, where it does not mutate the collection. It comes quite handy where you want to debug the output in the chain of stream operations

val l = (1..10).toList()

// Don't
l.filter it % 2 == 0 
	.map 
		println(it)
		it * it
	

// Do
l.filter it % 2 == 0 
	// Prints, but doesn't mutate the collection
	.also  println(it) 
	.map  it*it

Use let

Use let along with ?. null-safe (or elvis) operator, when you want to do a null check

// Don't
val user: User? = findUser()
if (user != null)
    println(user.name)


// Do
findUser()?.let  println(it.name) 
//or
findUser()?.name?.let(::println)

Use apply

You can use apply to initialize a mutable object. It returns the same object it operates on and comes handy in initializing the properties.

class Server 
    lateinit var host: String
    var port: Int = 0
    var numOfInstance: Int = 1
    var isCloudInstance: Boolean = true


// Don't
var server = Server()
server.host = "sg1234"
server.port = 8080
server.numOfInstance = 3

// Do
var server = Server().apply 
    host = "sg1234"
    port = 8080
    numOfInstance = 3

Initialize Map with values

Immutable map is initialized using mapOf and mutable map is initialized using mutableMapOf in Kotlin.

Example 1

Use shorthand to operator to map “Key” to “value” instead of initializing Pair each time

// Don't
val immutableMap = mapOf(
    Pair("A", 1),
    Pair("B", 2),
    Pair("C", 3))

val mutableMap = mutableMapOf(
    Pair("A", 1),
    Pair("B", 2),
    Pair("C", 3))

// Do
val immutableMap = mapOf(
    "A" to 1,
    "B" to 2,
    "C" to 3
)

val mutableMap = mutableMapOf(
    "A" to 1,
    "B" to 2,
    "C" to 3
)
Example 2

Map is also quite useful in Kotlin logging

var url = "http://localhost:8080/users"
var method = "GET"
var status = 200

logger.debug(mapOf("url" to url, "method" to method, "status" to status))

Multiline String

An easy way to create a multiline String is to wrap it in """.

// Don't
println("Twinkle, Twinkle Little Batn" +
        "How I wonder what you're at!n" +
        "Up above the world you fly,n" +
        "Like a tea tray in the sky.n" +
        "Twinkle, twinkle, little bat!n" +
        "How I wonder what you're at!")

// Do
println("""
        Twinkle, Twinkle Little Bat
        How I wonder what you're at!
        Up above the world you fly,
        Like a tea tray in the sky.
        Twinkle, twinkle, little bat!
        How I wonder what you're at!""")

Extension Function

Extension functions is very powerful feature in Kotlin to add new functionality in existing class such as String without even inheriting it. We can not do such things in Java and generally write a StringUtil class to do that.

// Don't
object StringUtil 
    fun capitalize(string: String): String
        return string.replaceFirstChar  it.uppercaseChar() 
    


println(StringUtil.capitalize("ashish"))
// Ashish

// Do
fun String.capitalize(): String 
    return replaceFirstChar  it.uppercaseChar() 


println("ashish".capitalize())
// Ashish

Source

LEAVE A REPLY

Please enter your comment!
Please enter your name here