Kotlin Code Smell 16 - Instance Type Checking for Polymorphism
Ditch the Type Checks: Let Your Code Dance to Polymorphism's Tune
Table of contents
TL;DR: Trust your collaborators. Don't check who they are. Ask them to do it instead.
Problems
Coupling: Objects are tightly coupled due to instance type checking.
Metamodel interference: The use of instance type checking interferes with the metamodel.
IFs: Excessive use of if statements.
Solutions
Avoid using
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, favor immutability, and you will never need if statements.
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 objects with accidental decisions and violates bijection since no such control exists in the real world. It is a code smell that indicates our models are not good enough.
Credits
ย