Python實現設計模式--02.工廠模式(Factory Pattern)
阿新 • • 發佈:2018-12-31
《設計模式》涉及到建立類的幾種模式,共同的也是最根本的原則就是:不要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是弱語言型別,又沒有抽象的概念,很難約束子類,這樣在設計工廠的時候務必保持類名清晰,使呼叫者一眼就知道能得到什麼產品。