前言
工厂模式(Factory Pattern
)是一种创建型设计模式,提供一个创建对象的接口,不暴露对象的创建过程。它将实例化对象的任务交给子类或具体实现,从而使得客户端代码与具体类解耦。
工厂模式主要分为以下三类:
1、简单工厂模式(Simple Factory
)
2、工厂方法模式(Factory Method
)
3、抽象工厂模式(Abstract Factory
)
实现
1、简单工厂模式
Kotlin
中可以借助伴生对象companion object
来实现工厂模式,客户端不需要知道具体产品类的类名,只需要创建将产品类型传给工厂即可,降低了客户端与具体产品类的耦合,适合产品类目较少且不变动的情况下。
当后续要不断增加产品类型,这种模式就不太适合了,新增产品需要修改工厂类,则会导致工厂类太过臃肿,不利于维护。
假设有个小产品生产工厂,生产不同类目的产品,新建产品接口、这个工厂只能生产的产品类目有篮球、牛奶、笔。
kotlin
interface Product {
fun doWhat()
}
//踢足球
class FootBall : Product {
override fun doWhat() {
println("Football can be played")
}
}
//喝牛奶
class Milk : Product {
override fun doWhat() {
println("Milk can be drunk")
}
}
//写字
class Pen :Product{
override fun doWhat() {
println("Pen can be write")
}
}
生产产品的过程如下,商务有牛奶的订单交由产线生产,客户端告诉产线生产牛奶即可。
kotlin
class SimpleFactory {
companion object {
fun createProduct(type: String): Product {
return when (type) {
"FootBall" -> { FootBall() }
"Milk" -> { Milk() }
"Pen" -> { Pen() }
else -> {
throw IllegalArgumentException("unKnow product type")
}
}
}
}
}
SimpleFactory.createProduct("Milk").doWhat() //输出 Milk can be drunk
SimpleFactory.createProduct("Cup").doWhat() //输出 UnKnow product type
2、工厂方法模式
在更复杂的场景中,可以使用接口或抽象类来定义工厂方法,这样可以允许不同的工厂类创建不同类型的对象。
kotlin
interface Factory{
fun createProduct():Product
}
/**
* 球生成工厂
*/
class BallFactory : Factory {
override fun createProduct(): Product {
return FootBall()
}
}
/**
* 牛奶生产工厂
*/
class MilkFactory : Factory {
override fun createProduct(): Product {
return Milk()
}
}
/**
* 笔生产工厂
*/
class PenFactory : Factory {
override fun createProduct(): Product {
return Pen()
}
}
创建产品的过程不放到不同的工厂中,每个工厂只生成对应的产品即可,实例化过程放到对应的子类中进行,但是这样的坏处就是增加类的数目,增加了系统的复杂性。
3、抽象工厂模式
抽象工厂模式提供一个接口,用于创建一系列相关或相互依赖的对象,而无需指定它们的具体类,但是这样也会增加系统的复杂性和类的数量。
假设牛奶厂家做活动,买一箱牛奶送一辆豪车,蒙牛和保时捷联合、伊利和宾利合作,牛奶和车要在同一工厂生产,这种情况可以使用抽象工厂模式来实现。
抽象工厂模式的核心是抽象工厂接口和具体工厂类,通常包括:
1、抽象产品、接口(AbstractProduct
)
kotlin
interface Milk {
fun taste()
}
interface Car {
fun slogan()
}
2、具体产品(ConcreteProduct
)
kotlin
class MengNiu : Milk {
override fun taste() {
println("【蒙牛】纯甑酸奶砀山黄桃燕麦味")
}
}
class YiLi : Milk {
override fun taste() {
println("【伊利】安慕希丹东草莓酸奶")
}
}
class Porsche : Car {
override fun slogan() {
println("only Porsche can beat Porsche")
}
}
class Bentley : Car {
override fun slogan() {
println("Bentley,Be Extraordinary")
}
}
3、抽象工厂(AbstractFactory
)
kotlin
/**
* 抽象工厂类,定义生产牛奶和车接口
*/
interface AbstractFactory {
fun createMilk(): Milk
fun createCar(): Car
}
4、具体工厂(ConcreteFactory
)
kotlin
//MengNiu同步生产活动蒙牛牛奶和保时捷
class FactoryMengNiu : AbstractFactory {
override fun createMilk(): Milk {
return MengNiu()
}
override fun createCar(): Car {
return Porsche()
}
}
//YiLi同步生产活动伊利牛奶和宾利
class FactoryYiLi: AbstractFactory {
override fun createMilk(): Milk {
return YiLi()
}
override fun createCar(): Car {
return Bentley()
}
}
5、客户端(Client
)
kotlin
val factoryA:AbstractFactory = FactoryMengNiu()
val mengNiuMilk = factoryA.createMilk()
mengNiuMilk.taste() //【蒙牛】纯甑酸奶砀山黄桃燕麦味
val porsche = factoryA.createCar()
porsche.slogan() // only Porsche can beat Porsche
val factoryB:AbstractFactory = FactoryYiLi()
val yiLiMilk = factoryB.createMilk()
yiLiMilk.taste() //【伊利】安慕希丹东草莓酸奶
val bentley = factoryB.createCar()
bentley.slogan() //Bentley,Be Extraordinary
总结
工厂模式在解耦对象创建和使用、提高系统扩展性和维护性方面具有明显优势,但在系统复杂性和管理难度上也存在一定的代价。选择是否使用工厂模式应基于系统需求的复杂程度和对象创建的复杂性。