1. 程式人生 > >Python實現設計模式--02.工廠模式(Factory Pattern)

Python實現設計模式--02.工廠模式(Factory Pattern)

設計模式》涉及到建立類的幾種模式,共同的也是最根本的原則就是:不要new物件!!!既然如此,告訴我你最先想到的是如何得到物件呢?沒錯,“你不讓我new,那你給我個get物件的工具吧,別的我不管”。這就是工廠模式,工廠模式是一種簡單又實用的模式,在各大框架到處可見,比如Java世界大名鼎鼎的spring,其本身就是一個大工廠。

工廠模式中,工廠的作用是解耦呼叫者和被呼叫者的關係,工廠模式又分為工廠方法模式和簡單工廠模式。我們先說工廠方法模式,下面舉個現實的栗子。

比如說一個鞋廠,生產皮鞋和球鞋,安利公司打電話來說給我一批皮鞋,恆大足球隊打電話說來給我一批球鞋,鞋廠很開心的按時交付了。我們用程式碼來模擬這個場景,鞋廠就是抽象工廠,其下兩個車間--皮鞋車間和球鞋車間--是具體的工廠,皮鞋和球鞋都是產品,安利和恆大是客戶端。下面是實現程式碼:

# 鞋,基類(抽象產品類)
class Shoe:
    def walk(self):
        pass


# 皮鞋(具體產品)
class LeatherShoe(Shoe):
    def walk(self):
        print("優雅的皮鞋,去拉客戶中")


# 球鞋(具體產品)
class SoccerShoe(Shoe):
    def walk(self):
        print("憤怒的球鞋,正在蹂躪草坪")


# 鞋廠,基類(抽象工廠)
class ShoeFactory:
    def make_shoe(self):
        pass


# 皮鞋車間(具體工廠)
class LeatherShoeFactory(ShoeFactory):
    def make_shoe(self):
        return LeatherShoe()


# 球鞋車間(具體工廠)
class SoccerShoeFactory(ShoeFactory):
    def make_shoe(self):
        return SoccerShoe()


# 安利打電話要鞋
def anli_call():
    factory = LeatherShoeFactory()
    for i in range(3):
        shoe = factory.make_shoe()
        shoe.walk()


# 恆大打電話要鞋
def hengda_call():
    factory = SoccerShoeFactory()
    for i in range(3):
        shoe = factory.make_shoe()
        shoe.walk()


if __name__ == '__main__':
    anli_call()
    hengda_call()

這裡模擬安利和恆大分別下單購了3雙鞋,執行結果如下:

優雅的皮鞋,去拉客戶中
優雅的皮鞋,去拉客戶中
優雅的皮鞋,去拉客戶中
憤怒的球鞋,正在蹂躪草坪
憤怒的球鞋,正在蹂躪草坪
憤怒的球鞋,正在蹂躪草坪
上面例子中的每個具體工廠都只生產一種產品,假設該鞋廠很牛逼,一個車間什麼鞋都能生產。我們去掉兩個子工廠,把父工廠改為這樣:
# 鞋廠,基類(抽象工廠)
class ShoeFactory:
    def make_shoe(self, name):
        if name == "LeatherShoe":
            return LeatherShoe()
        elif name == "SoccerShoe":
            return SoccerShoe()
        else:
            return None
客戶方法要改為如下:
# 安利打電話要鞋
def anli_call():
    factory = ShoeFactory()
    for i in range(3):
        shoe = factory.make_shoe("LeatherShoe")
        shoe.walk()


# 恆大打電話要鞋
def hengda_call():
    factory = ShoeFactory()
    for i in range(3):
        shoe = factory.make_shoe("SoccerShoe")
        shoe.walk()
執行結果和上面一下,這種被稱為簡單工廠模式。簡單工廠模式相對工廠方法模式程式碼複雜度有所降低,但是每次增加產品,就要修改工廠類,擴充套件性差。

讀者應該會納悶了,這什麼玩意,整這麼複雜,我幾行程式碼迴圈new幾個物件完事兒。是的,例子中這種簡單的實體物件是不需要工廠模式的,用它來舉例是因為它很能體現“工廠”的概念。說實話本人真正在專案中沒有用到工廠模式,都只是在框架裡見到它的出現,比如spring對bean對管理、json序列化生成單例類等。感覺只有在寫框架的時候才需要它,業務程式碼多是行為類,以策略模式居多,不過話說到此,是不是可以用工廠模式管理行為類呢?回頭我嘗試一下。

下面是我的一點感受: 工廠與產品之間是一種弱聯絡,將上面例子中的球鞋車間改為生產皮鞋,完全不會有任何問題,所以工廠模式需要良好的命名約定。再加上python是弱語言型別,又沒有抽象的概念,很難約束子類,這樣在設計工廠的時候務必保持類名清晰,使呼叫者一眼就知道能得到什麼產品。