源碼地址:https://github.com/weilanhanf/PythonDesignPatternsgit
在簡單工廠模式中,只提供了一個工廠類,該工廠類處於對產品類進行實例化的中心位置,它知道每個產品對象的建立細節,並決定什麼時候實例化哪個產品類。簡單工廠模式最大的缺點是當有新產品要加入到系統中時,必須修改工廠類,加入必要的處理邏輯,這違背了「開閉原則」。在簡單工廠模式中,全部的產品都是由同一個工廠建立,工廠類職責較重,業務邏輯較爲複雜,具體產品與工廠類之間的耦合度高,嚴重影響了系統的靈活性和擴展性,而工廠方法模式則能夠很好地解決這一問題。github
定義一個用於建立對象的接口,可是讓子類決定將哪個類實例化。工廠方法模式讓一個類的實例化延遲到其子類。spa
工廠方法模式就是簡單工廠模式的進一步抽像。因爲面向對象多態性,工廠方法模式保持了簡單工廠的有點同時克服了他的缺點。工廠方法模式中,核心的工廠被提高爲一個抽象類,將具體的建立工做交給他的子類完成。這個抽象的工廠類僅規定具體工廠實現的接口,而不明確指出如何實例化一個產品類,這使得工廠方法模式容許系統在不修改原有產品結構的狀況下輕鬆的引進新產品。設計
提供一個建立一系列相關或相互依賴對象的接口,而無須指定它們具體的類。3d
抽象工廠模式是全部形式的工廠模式中最爲抽象和最具通常性的一種形式。當系統所提供的工廠生產的具體產品並非一個簡單的對象,而是多個位於不一樣產品等級結構、屬於不一樣類型的具體產品時就可使用抽象工廠模式 ,抽象工廠模式中的具體工廠不僅是建立一種產品,它負責建立一族產品 當一個工廠等級結構能夠建立出分屬於不一樣產品等級結構的一個產品族中的全部對象時,抽象工廠模式比工廠方法模式更爲簡單、更有效率code
抽象工廠模式包含如下4個角色: AbstractFactory(抽象工廠) ConcreteFactory(具體工廠) AbstractProduct(抽象產品) ConcreteProduct(具體產品)對象
某快餐點餐檯的點餐系統。在一個大的觸摸顯示屏上,有三類能夠選擇的上餐品:漢堡等主餐、小食、飲料。當咱們選擇好本身須要的食物,支付完成後,訂單就生成了。blog
class Burger(): """ 漢堡 """ name="" price=0.0 type='BURGER' def getPrice(self): return self.price def setPrice(self,price): self.price=price def getName(self): return self.name class CheeseBurger(Burger): def __init__(self): self.name="cheese burger" self.price=10.0 class SpicyChickenBurger(Burger): def __init__(self): self.name="spicy chicken burger" self.price=15.0 class Snack(): """ 小食類 """ name = "" price = 0.0 type = "SNACK" def getPrice(self): return self.price def setPrice(self, price): self.price = price def getName(self): return self.name class Chips(Snack): def __init__(self): self.name = "chips" self.price = 6.0 class ChickenWings(Snack): def __init__(self): self.name = "chicken wings" self.price = 12.0 class Beverage(): """ 飲料 """ name = "" price = 0.0 type = "BEVERAGE" def getPrice(self): return self.price def setPrice(self, price): self.price = price def getName(self): return self.name class Coke(Beverage): def __init__(self): self.name = "coke" self.price = 4.0 class Milk(Beverage): def __init__(self): self.name = "milk" self.price = 5.0 #以上的Burger,Snack,Beverage,均可以認爲是該快餐店的產品,因爲只提供了抽象方法,咱們把它們叫抽象產品類,而cheese burger等6個由抽象產品類衍生出的子類,叫做具體產品類。
class FoodFactory(): """ 抽象工廠foodFactory爲抽象的工廠類,而burgerFactory,snackFactory,beverageFactory爲具體的工廠類。 """ type="" def createFood(self,foodClass): print(self.type," factory produce a instance.") foodIns=foodClass() return foodIns class BurgerFactory(foodFactory): def __init__(self): self.type="BURGER" class SnackFactory(foodFactory): def __init__(self): self.type="SNACK" class BeverageFactory(foodFactory): def __init__(self): self.type="BEVERAGE" if __name__=="__main__": burger_factory=burgerFactory() snack_factory=snackFactory() beverage_factory=beverageFactory() cheese_burger=burger_factory.createFood(cheeseBurger) print(cheese_burger.getName(),cheese_burger.getPrice()) chicken_wings=snack_factory.createFood(chickenWings) print(chicken_wings.getName(),chicken_wings.getPrice()) coke_drink=beverage_factory.createFood(coke) print(coke_drink.getName(),coke_drink.getPrice())
打印結果:接口
BURGER factory produce a instance.
cheese burger 10.0
SNACK factory produce a instance.
chicken wings 12.0
BEVERAGE factory produce a instance.
coke 4.0ip
在實例中,抽象工廠下共有三個具體工廠burgerFactory,snackFactory,beverageFactory,三個工廠分別對應,換言之就是生產三類產品burger,snack,beverage。
工廠方法用來建立客戶所須要的產品,同時還向客戶隱藏了哪一種具體產品類將被實例化這一細節 可以讓工廠自主肯定建立何種產品對象,而如何建立這個對象的細節則徹底封裝在具體工廠內部 在系統中加入新產品時,徹底符合開閉原則
系統中類的個數將成對增長,在必定程度上增長了系統的複雜度,會給系統帶來一些額外的開銷 增長了系統的抽象性和理解難度
客戶端不知道它所須要的對象的類(客戶端不須要知道具體產品類的類名,只須要知道所對應的工廠便可,具體產品對象由具體工廠類建立) 抽象工廠類經過其子類來指定建立哪一個對象
隔離了具體類的生成,使得客戶端並不須要知道什麼被建立 當一個產品族中的多個對象被設計成一塊兒工做時,它可以保證客戶端始終只使用同一個產品族中的對象 增長新的產品族很方便,無須修改已有系統,符合開閉原則
增長新的產品等級結構麻煩,須要對原有系統進行較大的修改,甚至須要修改抽象層代碼,這顯然會帶來較大的不便,違背了開閉原則
一個系統不該當依賴於產品類實例如何被建立、組合和表達的細節 系統中有多於一個的產品族,但每次只使用其中某一產品族 屬於同一個產品族的產品將在一塊兒使用,這一約束必須在系統的設計中體現出來 產品等級結構穩定,設計完成以後,不會向系統中增長新的產品等級結構或者刪除已有的產品等級結構