Skip to main content

Command Palette

Search for a command to run...

Kotlin Code Smell 15 - Helper Classes

Goodbye Helpers, Hello Clean Code!

Published
2 min read
Kotlin Code Smell 15 - Helper Classes
Y

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: Helpers are non-cohesive and messy subroutines that don't actually help.

Problems

  • Lack of readability

  • Violation of the Least Surprise Principle

  • Issue with Bijection

  • Usage of static methods

Solutions

  • Choose an appropriate name.

  • If the helper is a library, divide all the services into different methods.

  • Methods should always be associated with objects. Avoid using static methods, as they are also considered a code smell.

  • Refrain from extracting helpers into Anonymous Functions.

Sample Code

Wrong

object UserHelper {
    fun getFullName(user: User) =
        "${user.firstName} ${user.lastName}"

    fun getCategory(user: User) =
        if (user.points > 70) 'A' else 'B'
}

Note the use of static methods:

data class User(
    val firstName: String,
    val lastName: String,
    val points: Int
)

fun main() {
    val alice = User(
        firstName = "Alice",
        lastName = "Gray",
        points = 78
    )

    val fullName = UserHelper.getFullName(alice)
    val category = UserHelper.getCategory(alice)
}

Right

class FullNameFormatter(private val user: User) {
    val fullName: String
        get() = "${user.firstName} ${user.lastName}"
}

class CategoryCalculator(private val user: User) {
    val displayName: Char
        get() = if(user.points > 70) 'A' else 'B'
}

fun main() {
    val alice = User(
        firstName = "Alice",
        lastName = "Gray",
        points = 78
    )

    val fullName = FullNameFormatter(alice).fullName
    val category = CategoryCalculator(alice).displayName
}

Alternatively, the former Helper can be made stateless for reuse...

class FullNameFormatter {
    fun fullName(user: User): String =
        "${user.firstName} ${user.lastName}"
}

class CategoryCalculator {
    fun displayName(user: User): Char =
        if (user.points > 70) 'A' else 'B'
}

fun main() {
    val alice = User(
        firstName = "Alice",
        lastName = "Gray",
        points = 78
    )

    val fullName = FullNameFormatter().fullName(alice)
    val category = CategoryCalculator().displayName(alice)
}

Conclusion

The usage of helper classes is a well-established cultural practice and a legacy habit from structured programming.

However, these names are causing harm and should be reconsidered.

It is essential for developers to let go of old habits and be aware of the negative impact these names can have.

Credits

Kotlin Code Smells

Part 22 of 36

In this series, we will see several symptoms and situations that make us doubt the quality of our development. We will present possible solutions. Most are just clues. They are no hard rules.

Up next

Kotlin Code Smell 14 - Anonymous Functions Abusers

Closures in Check: Enhancing Code Maintainability

More from this blog

Yonatan Karp-Rudin | kotlin for backend developer skills | java for backend developer skills | SpringBoot | Tutorials

57 posts

Experienced Senior Software Engineer passionate about functional programming & Kotlin. Excels in app development, optimization, and team collaboration. Let's create something amazing!