?設計模式之工廠三兄弟
阿新 • • 發佈:2020-06-24
熊二:工廠模式三兄弟,聽說過沒?
熊大:......
熊二:工廠模式三兄弟是:簡單工廠模式、工廠方法模式、抽象工廠模式,這三種都是屬於建立型的設計模式。
之前你不是問如何進行App架構設計嗎?設計模式三兄弟就是很好的例子。
熊大:為什麼這麼說呢?
熊二:因為工廠模式三兄弟可以根據功能的複雜程度,進行升級和降級;根據功能改變,這擴充套件性不就體現出來了嗎,同時也能減小程式碼解耦程度,一舉多得。
建立型模式
工廠三兄弟 腦圖結構
建立型模式中的 工廠三兄弟適用於建立的物件有極大類似性的場景。
簡單工廠模式
簡單工廠模式,違反了設計原則中的開閉原則。我們具體看程式碼。
protocol Product {}
class ConcreteProductA: Product {}
class ConcreteProductB: Product {}
class Client {
let s = Factory()
}
class Factory {
func createProduct(type: Int) -> Product {
if type == 0 {
return ConcreteProductA()
} else {
return ConcreteProductB()
}
}
}
let c = Client()
c.s.createProduct(type: 0) // get ConcreteProductA
複製程式碼
分析:
每次新增一種type,都要修改if else ,即我們可能會頻繁修改內部核心程式碼,這就違反了開閉原則。
針對關於此段程式碼,我們再來分析一下。
第一點:
此程式碼是通過protocol 來實現的,不是定義父類,使用繼承關係;
個人認為protocol更適合橫向的,繼承更適合縱向的;
工廠模式使用繼承應該更好一點;
複製程式碼
第二點:
此外,type 不要出現 0、1、2、3之類的,
應該使用列舉,不然這些魔鬼數字不易讀懂;
我們的程式碼要具有可讀性,程式碼要讓人看著爽。
複製程式碼
第三點:
而且明顯,type未來會有很多個,所以考慮擴充套件性,這裡用if、else條件語句, 就不如swith 語句,在這裡 switch 將是更優雅、更具有擴充套件性的一種方式。 複製程式碼
為了方便接下來分析,程式碼展示我就不對程式碼進行修改,希望諸君知曉,如果有不同觀點,歡迎入群solo。程式碼是這位兄弟的
工廠模式
工廠模式相對於簡單工廠模式而言只是將建立工作分給了子類,依舊沒有解決簡單工廠模式關於違反開閉原則的問題。
protocol Product {} class ConcreteProductA: Product {} class ConcreteProductB: Product {} class Client { let f = Factory() } class Factory { func createProduct() -> Product? { return nil } // 用於繼承 func createProduct(type: Int) -> Product? { // 用於呼叫 if type == 0 { return ConcreteFactoryA().createProduct() } else { return ConcreteFactoryB().createProduct() } } } class ConcreteFactoryA: Factory { override func createProduct() -> Product? { // ... 產品加工過程 return ConcreteProductA() } } class ConcreteFactoryB: Factory { override func createProduct() -> Product? { // ... 產品加工過程 return ConcreteProductB() } } let c = Client() c.f.createProduct(type: 0) // get ConcreteProductA 複製程式碼
抽象工廠模式
簡單工廠模式、工廠模式生產都是同一種型別的產品,有共同的父類。
當你的產品需要用兩個及以上時就要升級成抽象工廠模式了。
protocol ProductA {} class ConcreteProductA1: ProductA {} class ConcreteProductA2: ProductA {} protocol ProductB {} class ConcreteProductB1: ProductB {} class ConcreteProductB2: ProductB {} class Client { let f = Factory() } class Factory { func createProductA() -> ProductA? { return nil } // 用於繼承 func createProductB() -> ProductB? { return nil } // 用於繼承 func createProductA(type: Int) -> ProductA? { // 用於呼叫 if type == 0 { return ConcreteFactory1().createProductA() } else { return ConcreteFactory2().createProductA() } } func createProductB(type: Int) -> ProductB? { // 用於呼叫 if type == 0 { return ConcreteFactory1().createProductB() } else { return ConcreteFactory2().createProductB() } } } class ConcreteFactory1: Factory { override func createProductA() -> ProductA? { // ... 產品加工過程 return ConcreteProductA1() } override func createProductB() -> ProductB? { // ... 產品加工過程 return ConcreteProductB1() } } class ConcreteFactory2: Factory { override func createProductA() -> ProductA? { // ... 產品加工過程 return ConcreteProductA2() } override func createProductB() -> ProductB? { // ... 產品加工過程 return ConcreteProductB2() } } let c = Client() c.f.createProductA(type: 0) // get ConcreteProductA1 c.f.createProductA(type: 1) // get ConcreteProductA2 c.f.createProductB(type: 0) // get ConcreteProductB1 c.f.createProductB(type: 1) // get ConcreteProductB2 複製程式碼
複製程式碼
關於三兄弟的升級與降級
單一型別產品比較少時,用簡單工廠模式。 單一型別產品各種定製比較多時,用工廠模式。 多種型別產品時,使用抽象工廠模式。
參考
本文程式碼段參考以下文章:
作者:darrenzheng
連結:https://juejin.im/post/5aaa2943f265da239c7b15c4
來源:掘金
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。
複製程式碼