1、簡單工廠模式
-
定義:簡單工廠模式又名靜態工廠方法模式,是由一個工廠對象決定創建出哪一種產品類的實例,包含:
- 產品工廠類(Factory):負責生產各種具體的產品,不關心產品產生的過程,只關心要生產的產品的類型
- 抽象產品類(IProduct):創建的所有對象的父類,它負責描述所有實例所共有的公共接口
- 具體產品類(Product):具體的產品,封裝了產品建造的過程以及使用的教程
-
簡單實現
- 不同手機型號需要使用不同的推送,可以集成小米、華為、極光推送然后創建一個工廠類根據手機型號來使用不同的推送。
- 1、定義推送調用的接口
/**
* 定義一個通用的push推送接口
* @author LTP 2021/11/10
*/
interface IPush {
/** 定義一個抽象的push方法 */
fun push()
}
/**
* 具體產品類:小米推送具體實現
* @author LTP 2021/11/10
*/
class MiPush : IPush {
override fun push() {
println("小米手機使用小米推送")
}
}
/**
* 具體產品類:華為推送具體實現
* @author LTP 2021/11/10
*/
class HuaWeiPush : IPush {
override fun push() {
println("華為手機使用華為推送")
}
}
/**
* 具體產品類:極光推送具體實現
* @author LTP 2021/11/10
*/
class JiGuangPush : IPush {
override fun push() {
println("其他手機使用極光推送")
}
}
/**
* 推送工廠類
* @author LTP 2021/11/10
*/
object PushFactory {
/**
* 根據具體的手機類型使用具體的推送服務
*
* @param type 推送類型
* @return Push 具體的推送類型
*/
fun createPush(type: String): IPush {
return when (type) {
"xiaoMi" -> MiPush()
"huaWei" -> HuaWeiPush()
else -> JiGuangPush()
}
}
}
/**
* 具體調用
*
* @author LTP 2021/11/10
*/
class CreatePush {
companion object {
@JvmStatic
fun main(args: Array<String>) {
PushFactory.createPush("xiaoMi").push()
PushFactory.createPush("huaWei").push()
}
}
}
執行結果:
小米手機使用小米推送
華為手機使用華為推送
-
使用場景與優缺點
-
使用場景:
- 1、工廠類負責創建的對象比較少。
- 2、客戶只知道傳入工廠類的參數,對于如何創建對象(邏輯)不關心
-
優點:用戶根據參數獲得對應的類實例,避免了直接實例化類,降低了耦合性
-
缺點:類型在編譯期間已經被確定,增加新類型需要修改工廠,違背了開放封閉原則(ASD) ;需要事先知道所有要生成的類型,當子類過多或者子類層次過多時不適合使用
2、工廠方法模式
-
定義:定義一個用于創建對象的接口,讓子類決定實例化哪個類。工廠方法使一個類的實例化延遲到其子類,包含:
- Product:抽象產品類。
- ConcreteProduct:具體產品類,實現Product接口。
- Factory:抽象工廠類,該方法返回一個Product類型的對象。
- ConcreteFactory:具體工廠類,返回ConcreteProduct實例。
-
簡單實現
- 現在來了一個新需求,在原來基礎上oppo手機需加入oppo推送,而且后面可能還會有更多手機廠商的推送...
-
實現步驟:
/**
* 推送抽象工廠類
* @author LTP 2021/11/10
*/
abstract class AbsPushFactory {
abstract fun <T : IPush> createPush(clazz: Class<T>): T
}
- 原來的工廠類繼承抽象工廠類利用反射來初始化各產品對象
/**
* @author LTP 2021/11/10
*/
object PushFactory : AbsPushFactory() {
override fun <T : IPush> createPush(clazz: Class<T>): T {
return Class.forName(clazz.name).getDeclaredConstructor().newInstance() as T
}
}
- 這是加入跟以前小米華為一樣,添加oppo推送的具體產品類......
/**
* 具體產品類:Oppo推送具體實現
* @author LTP 2021/11/10
*/
class OppoPush : IPush {
override fun push() {
println("oppo手機使用oppo推送")
}
}
/**
* 具體調用
*
* @author LTP 2021/11/10
*/
class CreatePush {
companion object {
@JvmStatic
fun main(args: Array<String>) {
PushFactory.createPush(MiPush::class.java).push()
PushFactory.createPush(HuaWeiPush::class.java).push()
PushFactory.createPush(OppoPush::class.java).push()
}
}
}
執行結果:
小米手機使用小米推送
華為手機使用華為推送
oppo手機使用oppo推送
-
優點:可以自由新增更多的產品線而不破壞開放封閉原則
-
缺點:使用反射,多多少少影響性能
3、抽象工廠模式
-
定義:為創建一組相關或者相互依賴的對象提供一個接口,而無需指定它們的具體類;
- AbstractFactory:抽象工廠,它聲明了用來創建不同產品的方法。
- ConcreteFactory:具體工廠,實現抽象工廠中定義的創建產品的方法。
- AbstractProduct:抽象產品,為每種產品聲明業務方法。
- ConcreteProduct:具體產品,定義具體工廠生產的具體產品,并實現抽象產品中定義的業務方法。
-
新需求
-
實現
/**
* 定義一個通用的發送短信接口
* @author LTP 2021/11/10
*/
interface ISend {
/** 定義一個抽象的send方法 */
fun send()
}
/**
* 具體產品類:小米短信具體實現(華為代碼同理已省略)
* @author LTP 2021/11/10
*/
class MiSend : ISend {
override fun send() {
println("小米手機發送小米短信")
}
}
/**
* 推送發短信抽象工廠類
* @author LTP 2021/11/10
*/
abstract class AbsPushSendFactory {
abstract fun createPush(): IPush
abstract fun createSend(): ISend
}
/**
* 華為工廠類
*
* @author LTP 2021/11/10
*/
class HuaWeiFactory : AbsPushSendFactory() {
override fun createPush(): IPush {
return HuaWeiPush()
}
override fun createSend(): ISend {
return HuaWeiSend()
}
}
/**
* 具體調用
*
* @author LTP 2021/11/10
*/
class CreatePushSend {
companion object {
@JvmStatic
fun main(args: Array<String>) {
// 小米工廠
val miFactory = MiFactory()
miFactory.createPush().push()
miFactory.createSend().send()
// 華為工廠
val huaWeiFactory = HuaWeiFactory()
huaWeiFactory.createPush().push()
huaWeiFactory.createSend().send()
}
}
}
執行結果:
小米手機使用小米推送
小米手機發送小米短信
華為手機使用華為推送
華為手機發送華為短信
-
使用場景與優缺點
-
使用場景:
- 1、一個系統不依賴于產品線實例如何被創建、組合和表達的細節。
- 2、系統中有多于一個的產品線,而每次只使用其中某一產品線。
- 3、一個產品線(或是一組沒有任何關系的對象)擁有相同的約束。
-
優點:具體類的創建實例過程與客戶端分離,客戶端通過工廠的抽象接口操縱實例,客戶端并不知道具體的實現是誰。
-
缺點:增加新的產品族則也需要修改抽象工廠和所有的具體工廠。
4、總結對比
- 簡單工廠模式:單一產品線固定產品;一個工廠類,無抽象工廠類
- 工廠模式:單一產品線可延伸產品(添加產品,只需添加IProduct的新產品實現類即可);一個抽象工廠類,所有產品共用一個工廠類
- 抽象工廠模式:固定多產品線可延伸產品(添加產品,需添加IProduct的新產品實現類以及新產品的工廠類);一個抽象工廠類,每一個產品都有一個工廠類