1. 程式人生 > Android開發 >?設計模式之工廠三兄弟

?設計模式之工廠三兄弟

熊二:工廠模式三兄弟,聽說過沒?

熊大:......

熊二:工廠模式三兄弟是:簡單工廠模式、工廠方法模式、抽象工廠模式,這三種都是屬於建立型的設計模式。

之前你不是問如何進行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
來源:掘金
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。
複製程式碼