抽象工厂与继承Kotlin

时间:2019-02-04 16:26:02

标签: design-patterns kotlin

我正在努力围绕Kotlin设计模式。我以Kotlin参考为起点创建了我的Abstract Factory

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类Foo继承。我该怎么办?像这样?我想念什么?还是我迷失了方向并没有意识到?

interface Plant

class OrangePlant : Plant

class ApplePlant : Plant

abstract class PlantFactory {
    abstract fun makePlant(foo: Foo): 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()
}

还是我应该添加到随播对象中?

1 个答案:

答案 0 :(得分:3)

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

abstract class PlantFactory : Foo() { ... }

这将使PlantFactory类型继承自Foo基类。和以前没什么不同。

我建议使用companion object来实现工厂。它会使代码缩短:

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.createFactory<OrangePlant>而不是OrangePlant.Factory

您可能仍然拥有该方法,就我而言,会有所不同:

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

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