Абстрактная фабрика и наследство Kotlin - PullRequest
0 голосов
/ 04 февраля 2019

Я пытаюсь обернуть голову вокруг шаблонов дизайна Kotlin.Я создал свой Abstract Factory, используя ссылку 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 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 голосов
/ 04 февраля 2019

Для наследования вы должны просто сказать

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, если вы охватите все дочерние классы

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...