Kotlin abstract factory pattern

How to write an abstract factory pattern in Kotlin

An example of an abstract factory pattern in Kotlin.

Table of contents for design patterns in Kotlin

The abstract factory pattern provides a way to encapsulate a group of individual factories that have a common theme without specifying their concrete classes. Wikipedia

Example:

Plant

interface Plant {
    val name get() = this.javaClass.simpleName
}

ApplePlant

class ApplePlant: Plant

OrangePlant

class OrangePlant: Plant

abstract class PlantFactory {

    abstract fun makePlant(): Plant

    companion object {
        inline fun <reified T: Plant> createFactory(): PlantFactory = when(T::class) {
            ApplePlant::class -> AppleFactory()
            OrangePlant::class -> OrangeFactory()
            else -> throw IllegalArgumentException()
        }
    }
}

AppleFactory

class AppleFactory: PlantFactory() {
    override fun makePlant(): Plant = ApplePlant()
}

OrangeFactory

class OrangeFactory : PlantFactory() {
    override fun makePlant(): Plant = OrangePlant()
}

Usage

fun main() {
    val appleFactory = PlantFactory.createFactory<ApplePlant>()
    val orangeFactory = PlantFactory.createFactory<OrangePlant>()

    with(appleFactory.makePlant()) {
        println(name)
    }
    with(orangeFactory.makePlant()) {
        println(name)
    }
}

Result

ApplePlant
OrangePlant