Design patterns 抽象工厂与继承Kotlin

Design patterns 抽象工厂与继承Kotlin,design-patterns,kotlin,Design Patterns,Kotlin,我正试图用Kotlin的设计模式来表达我的想法。我已经创建了我的抽象工厂,使用Kotlin引用作为起点 interface Plant class OrangePlant : Plant class ApplePlant : Plant abstract class PlantFactory { abstract fun makePlant(): Plant companion object { inline fun <reified T : Pl

我正试图用Kotlin的设计模式来表达我的想法。我已经创建了我的抽象工厂,使用Kotlin引用作为起点

interface Plant

class OrangePlant : Plant

class ApplePlant : Plant

abstract class PlantFactory {

    abstract fun makePlant(): Plant

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

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

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

或者我应该将其添加到同伴对象中吗?

对于继承,您应该简单地说

abstract class PlantFactory : Foo() { ... }
这将使
PlantFactory
类型从
Foo
基类继承。这和你以前拥有的没有区别

我建议使用
伴生对象
来实现工厂。它使代码短路:

interface Foo

interface Plant

class OrangePlant : Plant {
    companion object Factory : PlantFactory() {
        override fun makePlant() = OrangePlant()
    }
}

class ApplePlant : Plant {
    companion object Factory : PlantFactory() {
        override fun makePlant() = ApplePlant()
    }
}

abstract class PlantFactory : Foo {
    abstract fun makePlant(): Plant
}

fun main(args: Array<String>) {

    val foo1 : PlantFactory = OrangePlant.Factory
    val foo2 : PlantFactory = ApplePlant.Factory

    val orange = foo1.makePlant()
    val apple = foo2.makePlant()
}


对于类型化层次结构,使用
sealed
类可能是有意义的。Kotlin将允许编写
when
表达式,而不使用
else
语句,如果您涵盖所有子类

谢谢,这很有效。关于内联和具体化-我知道这些不会立即编译,这意味着除非调用它们,否则它们不会占用内存,并且在执行之后会被销毁。在你的例子中,这会是正确的吗@eugene petrenkoinline函数将被内联到调用站点,这意味着,方法体将被简化并放置,而不是函数调用。这就是允许在JVM上使用具体化泛型的技巧。它不需要额外的内存来运行,它只会使编译后的代码稍微长一点
interface Foo

interface Plant

class OrangePlant : Plant {
    companion object Factory : PlantFactory() {
        override fun makePlant() = OrangePlant()
    }
}

class ApplePlant : Plant {
    companion object Factory : PlantFactory() {
        override fun makePlant() = ApplePlant()
    }
}

abstract class PlantFactory : Foo {
    abstract fun makePlant(): Plant
}

fun main(args: Array<String>) {

    val foo1 : PlantFactory = OrangePlant.Factory
    val foo2 : PlantFactory = ApplePlant.Factory

    val orange = foo1.makePlant()
    val apple = foo2.makePlant()
}

inline fun <reified T : Plant> createFactory(): PlantFactory = when (T::class) {
    OrangePlant::class -> OrangePlant.Factory
    ApplePlant::class  -> ApplePlant.Factory
    else               -> throw IllegalArgumentException()
}