2-Python與設計模式--工廠類相關模式
一、快餐點餐系統
想必大家一定見過類似於麥當勞自助點餐檯一類的點餐系統吧。在一個大的觸控顯示屏上,有三類可以選擇的上餐品:漢堡等主餐、小食、飲料。當我們選擇好自己需要的食物,支付完成後,訂單就生成了。下面,我們用今天的主角--工廠模式--來生成這些食物的邏輯主體。
首先,來看主餐的生成(僅以兩種漢堡為例)。
class Burger(): name="" price=0.0 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(): 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"
同樣,foodFactory為抽象的工廠類,而burgerFactory,snackFactory,beverageFactory為具體的工廠類。
在業務場景中,工廠模式是如何“生產”產品的呢?
if __name__=="__main__": burger_factory=burgerFactory() snack_factorry=snackFactory() beverage_factory=beverageFactory() cheese_burger=burger_factory.createFood(cheeseBurger) print cheese_burger.getName(),cheese_burger.getPrice() chicken_wings=snack_factorry.createFood(chickenWings) print chicken_wings.getName(),chicken_wings.getPrice() coke_drink=beverage_factory.createFood(coke) print coke_drink.getName(),coke_drink.getPrice()
可見,業務中先生成了工廠,然後用工廠中的createFood方法和對應的引數直接生成產品例項。
列印結果如下:
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.0
二、工廠模式、簡單工廠模式、抽象工廠模式
工廠模式的定義如下:定義一個用於建立物件的介面,讓子類決定例項化哪個類。工廠方法使一個類的例項化延遲到其子類。其通用類圖如下。其產品類定義產品的公共屬性和介面,工廠類定義產品例項化的“方式”。
在上述例子中,工廠在使用前必須例項化。如果,把工廠加個類方法,寫成如下形式:
class simpleFoodFactory(): @classmethod def createFood(cls,foodClass): print "Simple factory produce a instance." foodIns = foodClass() return foodIns
在場景中寫成如下形式:
spicy_chicken_burger=simpleFoodFactory.createFood(spicyChickenBurger)
這樣,省去了將工廠例項化的過程。這種模式就叫做簡單工廠模式。
還是在上述例子中,createFood方法中必須傳入foodClass才可以指定生成的food例項種類,如果,將每一個細緻的產品都建立對應的工廠(如cheeseBurger建立對應一個cheeseBurgerFactory),這樣,生成食物時,foodClass也不必指定。事實上,此時,burgerFactory就是具體食物工廠的一層抽象。這種模式,就是抽象工廠模式。
三、工廠模式的優點和應用
工廠模式、抽象工廠模式的優點:
1、工廠模式巨有非常好的封裝性,程式碼結構清晰;在抽象工廠模式中,其結構還可以隨著需要進行更深或者更淺的抽象層級調整,非常靈活;
2、遮蔽產品類,使產品的被使用業務場景和產品的功能細節可以分而開發進行,是比較典型的解耦框架。
工廠模式、抽象工廠模式的使用場景:
1、當系統例項要求比較靈活和可擴充套件時,可以考慮工廠模式或者抽象工廠模式實現。比如,
在通訊系統中,高層通訊協議會很多樣化,同時,上層協議依賴於下層協議,那麼就可以對應建立對應層級的抽象工廠,根據不同的“產品需求”去生產定製的例項。
四、工廠類模式的不足
1、工廠模式相對於直接生成例項過程要複雜一些,所以,在小專案中,可以不使用工廠模式;
2、抽象工廠模式中,產品類的擴充套件比較麻煩。畢竟,每一個工廠對應每一類產品,產品擴充套件,就意味著相應的抽象工廠也要擴充套件