Kotlin实现工厂方法和抽象工厂设计模式

工厂方法设计模式

工厂方法设计模式,它的核心作用就是通过一个工厂隐藏对象实例的创建逻辑,而不需要暴露给客户端,实现解耦。

典型的使用场景就是当拥有一个父类与多个子类的时候,我们可以通过这种模式来创建子类对象。比如下面的业务场景:一个电脑加工厂,同时生产个人电脑和服务器主机。

package com.agg.kotlinapplication

interface Computer {
    val cpu: String

    companion object Factory {
        operator fun invoke(type: ComputerType): Computer {
            return when (type) {
                ComputerType.PC -> PC()
                ComputerType.Server -> Server()
            }
        }
    }
}

class PC(override val cpu: String = "Core") : Computer

class Server(override val cpu: String = "Xeon") : Computer

enum class ComputerType {
    PC, Server
}

fun main(args: Array<String>) {
    println(Computer.Factory(ComputerType.PC).cpu) // Core
}

companion object Factory:通过伴生对象创建静态工厂方法 ,方便调用。

operator fun invoke:通过运算符重载,简化方法的调用。注:()就是重载过的invoke方法。

抽象工厂设计模式

抽象工厂设计模式,为创建一组相关或相互依赖的对象提供一个接口,而且无须指定它们的具体类。

在上面的工厂方法设计模式中,我们已经很好的解决了电脑厂商生产服务器、PC机的问题,但是如果现在有好几个不同的电脑品牌,如Dell、Asus、Acer,那么就有必要在增加一个工厂类,此时可以采用抽象工厂设计模式,代码如下:

package com.agg.kotlinapplication

interface Computer

class Dell : Computer
class Asus : Computer
class Acer : Computer
class DellFactory : AbstractFactory() {
    override fun produce() = Dell()
}

class AsusFactory : AbstractFactory() {
    override fun produce() = Asus()
}

class AcerFactory : AbstractFactory() {
    override fun produce() = Acer()
}

abstract class AbstractFactory {
    abstract fun produce(): Computer

    companion object {
        inline operator fun <reified T : Computer> invoke(): AbstractFactory =
            when (T::class) {
                Dell::class -> DellFactory()
                Asus::class -> AsusFactory()
                Acer::class -> AcerFactory()
                else -> throw IllegalArgumentException()
            }
    }
}

fun main(args: Array<String>) {
    println(AbstractFactory<Dell>().produce()) // com.agg.kotlinapplication.Dell@f6f4d33
}

 inline operator fun <reified T : Computer> invoke():通过将invoke方法用inline定义为内联函数,进而可以引用reified关键字,使用具体化参数类型的语法特性。

Kotlin和Java一样,由于运行时的类型擦除,并不能直接获取一个参数的类型,然而内联函数会直接在字节码中生成相应的函数体实现,这种情况下我们就可以获取参数的具体类型。

参考:【Kotlin核心编程-水滴技术团队】

发布了55 篇原创文章 · 获赞 61 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/Agg_bin/article/details/104331797
今日推荐