Kotlin Code Smell 016 - Instance Type Checking For Polymorphism
Do you check who are you talking to?
Play this article
Table of contents
TL;DR: Trust your collaborators. Don't check who they are. Ask them to do it instead.
Problems
Solutions
Avoid
is
,as
,::class
,::class.java
, etc...Don't use Reflection and Meta-programming for Domain Objects.
Replace IFs with polymorphism.
Use complete objects, avoid nulls and setters, favor immutability and you will never ifs.
Sample Code
Wrong
class Rabbit {
fun run() = println("I'm running! 🏃")
}
class Seagull {
fun fly() = println("I'm flying! ✈️")
}
fun move(animal: Any) =
when(animal) {
is Rabbit -> animal.run()
is Seagull -> animal.fly()
else -> throw IllegalArgumentException("Unknown animal type")
}
fun main() {
val bunny = Rabbit()
val livingstone = Seagull()
move(bunny)
move(livingstone)
}
Right
abstract class Animal {
abstract fun move()
}
class Rabbit : Animal() {
override fun move() = println("I'm running! 🏃")
}
class Seagull : Animal() {
override fun move() = println("I'm flying! ✈️")
}
fun main() {
val bunny = Rabbit()
val livingstone = Seagull()
bunny.move()
livingstone.move()
}
Conclusion
Testing for a class type couples the objects with accidental decisions and violates bijection since no such control exists in the real world. It is a smell our models are not good enough.