首页 > 解决方案 > 抽象工厂和继承 Kotlin

问题描述

我正在尝试围绕 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 继承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()
}

还是我应该寻找添加到伴随对象中?

标签: design-patternskotlin

解决方案


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

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


推荐阅读