3-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
最終,我們是要建造一個訂單,因而,需要一個訂單類。假設,一個訂單,包括一份主食,一份小食,一種飲料。(省去一些異常判斷)
class order(): burger="" snack="" beverage="" def __init__(self,orderBuilder): self.burger=orderBuilder.bBurger self.snack=orderBuilder.bSnack self.beverage=orderBuilder.bBeverage def show(self): print "Burger:%s"%self.burger.getName() print "Snack:%s"%self.snack.getName() print "Beverage:%s"%self.beverage.getName()
程式碼中的orderBuilder是什麼鬼?這個orderBuilder就是建造者模式中所謂的“建造者”了,先不要問為什麼不在order類中把所有內容都填上,而非要用builder去建立。接著往下看。
orderBuilder的實現如下:
class orderBuilder(): bBurger="" bSnack="" bBeverage="" def addBurger(self,xBurger): self.bBurger=xBurger def addSnack(self,xSnack): self.bSnack=xSnack def addBeverage(self,xBeverage): self.bBeverage=xBeverage def build(self): return order(self)
在場景中如下去實現訂單的生成:
if __name__=="__main__": order_builder=orderBuilder() order_builder.addBurger(spicyChickenBurger()) order_builder.addSnack(chips()) order_builder.addBeverage(milk()) order_1=order_builder.build() order_1.show()
列印結果如下:
Burger:spicy chicken burger
Snack:chips
Beverage:milk
二、建造者模式
建造者模式的定義如下:將一個複雜物件的構建與它的表示分離,使得同樣的構建過程可以建立不同的表示。
建造者模式的作用,就是將“構建”和“表示”分離,以達到解耦的作用。在上面訂單的構建過程中,如果將order直接通過引數定義好(其構建與表示沒有分離),同時在多處進行訂單生成,此時需要修改訂單內容,則需要一處處去修改,業務風險也就提高了不少。
在建造者模式中,還可以加一個Director類,用以安排已有模組的構造步驟。對於在建造者中有比較嚴格的順序要求時,該類會有比較大的用處。在上述例子中,Director實現如下:
class orderDirector(): order_builder="" def __init__(self,order_builder): self.order_builder=order_builder def createOrder(self,burger,snack,beverage): self.order_builder.addBurger(burger) self.order_builder.addSnack(snack) self.order_builder.addBeverage(beverage) return self.order_builder.build()
通過createOrder直接代入引數,即可直接生成訂單。
三、建造者模式的優點和使用場景
優點:
1、封裝性好,使用者可以不知道物件的內部構造和細節,就可以直接建造物件;
2、系統擴充套件容易;
3、建造者模式易於使用,非常靈活。在構造性的場景中很容易實現“流水線”;
4、便於控制細節。
使用場景:
1、目標物件由元件構成的場景中,很適合建造者模式。例如,在一款賽車遊戲中,車輛生成時,需要根據級別、環境等,選擇輪胎、懸掛、骨架等部件,構造一輛“賽車”;
2、在具體的場景中,物件內部介面需要根據不同的引數而呼叫順序有所不同時,可以使用建造者模式。例如:一個植物養殖器系統,對於某些不同的植物,澆水、施加肥料的順序要求可能會不同,因而可以在Director中維護一個類似於佇列的結構,在例項化時作為引數代入到具體建造者中。
四、建造者模式的缺點
1、“加工工藝”對使用者不透明。(封裝的兩面性)