工廠模式是一種設計模式。工廠顧名思義就是生產產品的地方,我們會宣告一個工廠類別,當我們需要產品的時候,就呼叫工廠類別,工廠就會回傳一個實例化的物件給我們。工廠模式又分成簡單工廠模式、工廠模式及抽象工廠模式。
以下用Kotlin來講解
簡單工廠模式是管理物件創建的地方,傳入不同的參數,會回傳不同的物件。使用者只要傳入正確參數,不需要理解這個物件是如何創建的。
舉個例子,現在我們要設計一個培訓冒險者的訓練營,裡面可以訓練兩種職業,弓箭手與鬥士。套到工廠模式中,我們會需要宣告一個冒險者類別(父類別)(介面),一個繼承並實作它的弓箭手類別及一個鬥士類別,以及一個訓練營類別,也就是簡單工廠類別。
// 冒險者
interface Adventurer {
val type: String?
}
// 弓箭手
class Archer : Adventurer {
override val type = "我是弓箭手"
}
// 鬥士
class Warrior : Adventurer {
override val type = "我是鬥士"
}
object TrainingCamp {
fun trainAdventurer(type: String?): Adventurer? {
return when (type) {
"archer" -> {
println("訓練一個弓箭手")
Archer()
}
"warrior" -> {
println("訓練一個鬥士")
Warrior()
}
else -> null
}
}
}
fun main(args: Array<String>) {
val memberA = TrainingCamp.trainAdventurer("archer")
val memberB = TrainingCamp.trainAdventurer("warrior")
println(memberA?.type)
println(memberB?.type)
}
執行結果:
訓練一個弓箭手
訓練一個鬥士
我是弓箭手
我是鬥士
簡單工廠模式因為只有一個工廠,新增產品類別時會需要直接修改工廠內部的程式碼,破壞了開放/封閉原則。在這裡我們將工廠提升為抽象介面,這個工廠介面只會規範其子類別應該回傳哪種產品,實際上要如何製作產品則交給子類別各自實作。
現在工廠已被提升為一種概念,每種冒險者的訓練過程應該是不同的,例如訓練後勤掩護的弓箭手與訓練進戰的鬥士應該是不同的培訓過程,不能像以前一樣一個訓練營訓練出所有種類的冒險者。
interface Adventurer {
val type: String?
}
// 弓箭手
class Archer : Adventurer {
override val type = "我是弓箭手"
}
// 鬥士
class Warrior : Adventurer {
override val type = "我是鬥士"
}
interface TrainingCamp{
fun trainAdventurer():Adventurer
}
object ArcherTrainingCamp:TrainingCamp {
override fun trainAdventurer(): Adventurer {
println("訓練一個弓箭手")
return Archer()
}
}
object WarriorTrainingCamp:TrainingCamp {
override fun trainAdventurer(): Adventurer{
println("訓練一個鬥士")
return Warrior()
}
}
fun main(args: Array<String>) {
val memberA = ArcherTrainingCamp.trainAdventurer()
val memberB = WarriorTrainingCamp.trainAdventurer()
println(memberA?.type)
println(memberB?.type)
}
執行結果:
訓練一個弓箭手
訓練一個鬥士
我是弓箭手
我是鬥士
新手村現在建立了兩座訓練營,弓箭手訓練營、鬥士訓練營。如此一來,若想修改弓箭手的訓練流程,就修改弓箭手訓練營裡的程式碼即可,不用擔心會影響鬥士訓練營的運作,而且如要增加冒險者的類別,例如劍士,只要新增一座劍士訓練營,完全不會改動到抽象訓練營與本來的實體訓練營。
累惹,今天先到這,明天再來講抽象工廠。