工厂方法设计模式
工厂方法设计模式,它的核心作用就是通过一个工厂隐藏对象实例的创建逻辑,而不需要暴露给客户端,实现解耦。
典型的使用场景就是当拥有一个父类与多个子类的时候,我们可以通过这种模式来创建子类对象。比如下面的业务场景:一个电脑加工厂,同时生产个人电脑和服务器主机。
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核心编程-水滴技术团队】