Kotlin Code Smell 23 - Singletons

Kotlin Code Smell 23 - Singletons

One Too Many: The Slippery Slope of Singleton Patterns


  • Coupling

  • Testability

  • Accidental implementation problems

  • Multi-threading issues

  • Static methods polluting

  • Object creation contract violation

  • Bijection mismatch

  • Memory issues

  • Premature Optimization


  1. Avoid singletons altogether.

  2. Use contextual unique objects instead of relying on a global instance.

  3. Benchmark object creation to ensure performance is not adversely affected.


  • Database Access

  • Globals

  • Loggers

  • Helper classes

Sample Code


// God is the archetypal singleton example
class God {
    // In Kotlin, the companion object is always a singleton
    companion object {
        private var instance: God? = null

        fun getInstance(): God {
            if (instance == null) {
                instance = God()

            return requireNotNull(instance)

// Why should we be aware of getInstance when creating an object?
val jewishGod = God.getInstance()


interface Religion {
    // Define behavior

class God {
    // There can be as many as you wish

class PolytheisticReligion(private val gods: Collection<God>) : Religion
class MonotheisticReligion(private val godAllMighty: God) : Religion

// According to Judaism, there's only one God,
// but this does not hold in other religions.
// Under this context, God is unique. We cannot create or change
// a new one.
val jewishGod = God()
val judaism = MonotheisticReligion(jewishGod)

val jupiter = God()
val saturn = God()
val mythologicalReligion = PolytheisticReligion(listOf(jupiter, saturn))

// Gods are unique (or not) according to context.
// We can create test religions with or without unicity.
// This is less coupled since we break the direct reference to the
// God class.
// The God class has the single responsibility to create gods, not
// to manage them.


The use of singletons is a historical mistake that has already been acknowledged by the community. Nevertheless, lazy developers bring it up again and again. We need to reach a consensus on its drawbacks and strive for better design patterns.


Did you find this article valuable?

Support Yonatan Karp-Rudin by becoming a sponsor. Any amount is appreciated!