Speedy Development

&

Clean Code

with

Kotlin

Clean code?

  • Simple
  • Minimal noise/ceremony
  • Concise
  • Readable

Functions

Rule 1: Functions should be small!
Rule 2: Functions should be smaller than that!
Clean Code by Robert C. Martin, page 34
 
// Java
public Product parseProduct(Response response){
   if (response == null){
       throw new ClientException("Response is null");
   }
   int code = response.code();
   if (code == 200 || code == 201){
       return mapToDTO(response.body());
   }
   if (code >= 400 && code <= 499){
      throw new ClientException("Sent an invalid request");
   }
   if (code >= 500 && code <= 599){
       throw new ClientException("Server error");
   }
   throw new ClientException("Error. Code " + code);
}
// Kotlin
fun parseProduct(response: Response?) = when (response?.code()){
   null -> throw ClientException("Response is null")
   200, 201 -> mapToDTO(response.body())
   in 400..499 -> throw ClientException("Sent an invalid request")
   in 500..599 -> throw ClientException("Server error")
   else -> throw ClientException("Error. Code ${response.code()}")
}


//when is like the java switch, just more power

No Side Effects

  • Expressions
  • Immutability

Pure functions

Flow control structures are expressions

val message = try {
    JSONObject(json).getString("message")
} catch (ex: JSONException) {
    json
}

//try block can return values
fun getMessage(json: String) = try {
    JSONObject(json).getString("message")
} catch (ex: JSONException) {
    json
}

Single Expression Function

Immutability

public class Person {
    String name;
    String address;
    String career;
    int age;
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getCareer() {
        return career;
    }

    public void setCareer(String career) {
        this.career = career;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

POJO

Immutable data class

data class Person(
     val name:String = "", 
     val age:Int = 0, 
     val address:String = "",
     val career:String = ""
)
//Easy Object creation
val person = Person("Smile", 102, "Surulere, LG", "Repairman") 



//as to

Person person = new Person("Smile", 102, "Surulere, LG", "Repairman");

Error handling

Type system

  • Nullable
  • Non-nullable
val value: String = "non-nullable reference"
val value: String = null // compile error! Can't assign null to non-null type.

val nullableValue: String? = "nullable reference"
val nullableValue: String? = null

val value: String = nullableValue
//compile error! Can't assign nullable value to non-null
val value: String = if (nullableValue == null) "default" else nullableValue

To assign nullable type to non-null

preferrably

val value: String = nullableValue ?: "default"

Conclusion

  • Increased readability(less boilerplate & ceremony)
  • Increased safety
  • kotlin encourages good design

*Note

  • Clean code is also a construct from the coder(discipline is needed)
  • Sometimes old means might be better, make comparisons

References

  • https://kotlinlang.org/
  • https://blog.philipphauer.de/idiomatic-kotlin-best-practices/
  • https://medium.com/@Pinterest_Engineering/anything-java-can-do-kotlin-can-do-better-a1c1ddae8ffd

Community

  • kotlinnigeriaug.slack.com
  • https://www.meetup.com/Kotlin-Nigeria-User-Group/
  • https://kotlinlang.org/community/