Python 設計模式之建造者模式 Builder Pattern

 #引入建造者模式

肯德基的菜單上有 薯條, 雞腿,雞翅,雞米花,可樂,橙汁,火腿漢堡,至尊蝦漢堡,牛肉漢堡 , 雞肉卷等這些單品,也有不少套餐。html

好比java

套餐1:雞翅,至尊蝦漢堡,可樂,薯條python

套餐2:雞腿,火腿漢堡,橙汁,薯條編程

套餐3: 。。。。。segmentfault

全家桶:。。。。。ui

這種有各類各樣的單品一步一步生成各類套餐, 這種過程稱的上建造者模式htm

 

 使用多個簡單的對象一步一步構建成一個複雜的對象,有點像造房子同樣一步步從地基作起到萬丈高樓。我想這也是爲何被稱呼爲建造者模式的緣由吧!對象

 

 

 

 #建造者定義

 Separate the construction of a complex object from its representation so that the same construction process can create different representations.
將一個複雜對象的構建與它的表示進行分離,使得一樣的構建過程能夠建立不一樣的表示。blog

 

 這個定義裏面的 ‘不一樣的表示’ 意思是不一樣的產品, 或者是不一樣的功能。接口

簡單理解:建造者模式(Builder Pattern) 具有兩層含義:

  • 構建與表示分離構建 表明對象建立,表示 表明對象行爲/方法,也就是對象的建立與行爲進行分離(對應到 java 代碼,其實就是使用 接口 規定行爲,而後由具體的實現類進行構建)。
  • 建立不一樣的表示:也就是具有一樣的行爲,可是卻因爲構建的行爲順序不一樣或其餘緣由能夠建立出不一樣的表示。

咱們看完上述 建造者模式 的定義,就知道它與 工廠模式 是很是類似的。構建與表示分離建立不一樣的表示 對於 工廠模式 一樣具有。建造者模式 惟一區別於 工廠模式 主要是針對 複雜對象的構建

也就是說,若是是建立簡單對象,咱們一般都是使用 工廠模式 進行建立;而若是是建立複雜對象,那麼此時就能夠考慮使用 建造者模式。

 

 

#主要解決

當須要構建的產品具有 複雜建立 過程時,能夠抽取出共性構建過程,而後交由具體實現類自定義構建流程,使得一樣的構建行爲能夠生產出不一樣的產品,分離了構建與表示,使構建產品靈活性大大增長。

 

 

#使用場景

看到上面的模式定義內容,能夠根據內容剝離出這個模式的使用場景

1)須要生成的產品對象有複雜的內部結構,這些產品對象具有共性;

2)隔離複雜對象的建立和使用,並使得相同的構建過程能夠建立不一樣的產品。

 

 #建造者模式的優勢

我在百度文庫裏看到了這個做者的文章,我喜歡ta的表述,不能複製,我就敲下來放這裏了

1)在建造者模式中,客戶端沒必要知道產品內部組成的細節,將產品自己與產品的建立進行解耦,使得相同的建立過程能夠建立不一樣的產品對象

2)每個具體建造者都是獨立的,與其餘的具體建造者無關,,所以能夠很方便的替換具體建造者或增長具體建造者,用戶使用不一樣的具體建造者可獲得不一樣的產品對象,因爲指揮者類針對抽象建造者編程,增長新的具體建造者無需修改原有類庫的代碼,系統擴展方便,符合開閉原則。在編寫代碼中,代碼複用率是尤其重要的

3)用戶能夠更爲精細的控制產品的建立過程,將複雜的產品的建立步驟分解在不一樣的方法中,使得建立過程更加清晰,也更方便使用程序來控制建立過程

 

#建造者模式的缺點

1)建造者模式所建立的產品通常具備較多的共同點,其組成部分類似,若是產品之間的差別性較大,例如不少組成部分不相同,則不適合使用建造者模式,所以使用範圍受到必定的限制

2)若是產品的內部變化複雜,可能須要不少具體建造者類類實現這種變化,致使系統變得龐大,增長了系統的理解難度和運行成本

 

 

 

 

#建造者模式 主要包含四種角色:

1)抽象建造者(Builder):主要用於規範產品類的各個組成部分,並提供一個返回完整產品的接口。

2)具體建造者(Concrete Builder):實現 抽象建造者 規定的各個方法,返回一個組件好的具體產品。

3)產品(Product):構建至關複雜的類型,建造者最終建立的產品類型。

4)導演者(Director):指導 建造者(Builder) 以特定行爲構建出產品,並將其返回給客戶。

總結:理解了 建造者模式 的四種角色,其實就已經掌握了 建造者模式 的真諦:建造者模式 最終返回一個具體的構建複雜的產品;系統中產品可能只有一種類型或多種類型,但對某些產品族來講,它們具有相同的行爲,所以對這些共性行爲進行抽象,抽離出 抽象建造者(Builder);而對這些行爲的具體構建過程,則交由 具體建造者(Concrete Builder) 負責,不一樣的 具體建造者 會構建出不一樣表示的產品;而具體要構建出哪一種產品,由 導演者(Director) 決定。導演者 會選擇不一樣的 具體建造者,指導它構建出產品。

 

#注意,也能夠靜態內部類實現 建造者模式

事實上,在日常的代碼中,咱們一般都會忽略對象的複雜性,使用 工廠模式 建立對象,而不是 建造者模式。正如上文所講,工廠模式 和 建造者模式 的做用都是用於建立一個產品對象,而 工廠模式 結構更加簡潔直接(沒有 Builder 和 Director),所以更常使用。

而 建造者模式,咱們更加習慣使用 靜態內部類 的方式進行實現,即一個 產品類 內部自動帶有一個 具體建造者(Concrete Builder),由它負責該產品的組裝建立。再也不須要 抽象建造者(Builder) 和 導演者(Director),這樣,使得產品與構建之間的聯繫更加緊密,結構更加緊湊,同時使得 建造者模式 形式更加簡潔。

 

 

#舉個例子

 這個訂單系統的例子很容易理解,做者寫的有點冗餘,不過徹底能說明這是一個建造者模式

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())

# 建造者
class orderBuilder():
    """
    orderBuilder就是建造者模式中所謂的「建造者」,
    將訂單的建造與表示相分離,以達到解耦的目的。
    在上面訂單的構建過程當中,若是將order直接經過參數定義好(其構建與表示沒有分離),
    同時在多處進行訂單生成,此時須要修改訂單內容,
    則須要一到處去修改,業務風險也就提升了很多。
    """
    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)

# Director類
class orderDirector():
    """
    在建造者模式中,還能夠加一個Director類,用以安排已有模塊的構造步驟。
    對於在建造者中有比較嚴格的順序要求時,該類會有比較大的用處。
    """
    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()

#場景實現
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()

 

 

 

 

#參考

https://www.jianshu.com/p/47329a94f5dc

https://wenku.baidu.com/view/34a8a76cb9f67c1cfad6195f312b3169a451ea99.html

https://segmentfault.com/a/1190000019414444?utm_source=tag-newest

https://www.jianshu.com/p/9a90ca0fc24f

https://www.cnblogs.com/welan/p/9124081.html

相關文章
相關標籤/搜索