Kotlin Code Smell 14 - Anonymous Functions Abusers
Closures in Check: Enhancing Code Maintainability

I've started to work as a software engineer at 2014, however, I started to write code at high-school.
My first language was Assembly, but still, I fall in love with the possibilities to make the computer to do as you wish, shortly after that I started to write in C.
Later on I studied a practical engineering in electricity, and during this time discovered that I preferred much more writing code than design electrical components.
As a result of this understanding I decided to switch and study bachelor degree in computer science in Reichman university, where the focus was of the Java language.
Today I'm working at SumUp using Kotlin, SpringBoot & Micronaut, Cassandra and Kafka
TL;DR: Avoid excessive use of closures and functions. Encapsulate them within objects.
Problems
Maintainability
Testability
Code Reuse
Implementation Hiding
Debugging
Solutions
Wrap functions/closures
Reify algorithms using a method object / Strategy pattern
Sample Code
Wrong
fun sortFunction(
list: MutableList<Int>,
fn: (Int, Int) -> Boolean
) {
for (i in list.indices) {
for (j in 0 until list.size - i - 1) {
if (fn(list[j], list[j + 1])) {
val temp = list[j]
list[j] = list[j + 1]
list[j + 1] = temp
}
}
}
}
fun main() {
val scores = mutableListOf(9, 5, 2, 7, 23, 1, 3)
sortFunction(scores) { a, b -> a > b }
}
Right
class ElementComparator {
fun greaterThen(firstElement: Int, secondElement: Int) =
firstElement > secondElement
// This is just an example. With more complex objects,
// this comparison might not be so trivial...
}
class BubbleSortStrategy(
private val elements: MutableList<Int>,
private val comparator: ElementComparator
) {
// We have a strategy; we can unit test it, change it to a
// polymorphic implementation, or benchmark different algorithms, etc.
fun sort() {
for (i in elements.indices) {
for (j in 0 until elements.size - i - 1) {
if (comparator.greaterThen(elements[j], elements[j + 1])) {
swap(j)
}
}
}
}
private fun swap(index: Int) {
val temp = elements[index]
elements[index] = elements[index + 1]
elements[index + 1] = temp
}
}
fun main() {
val scores = mutableListOf(9, 5, 2, 7, 23, 1, 3)
BubbleSortStrategy(scores, ElementComparator()).sort()
}
Conclusion
Humans read code, and while software can handle anonymous functions, maintainability suffers when multiple closures are used. By extracting functionality into objects, we can improve code reuse and maintainability.




