亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專(zhuān)欄INFORMATION COLUMN

python設(shè)計(jì)模式-抽象工廠模式

seal_de / 1969人閱讀

摘要:源碼參考抽象工廠模式抽象工廠模式提供一個(gè)接口,用于創(chuàng)建相關(guān)或依賴(lài)對(duì)象的家族,而不需要指定具體類(lèi)。工廠方法模式和抽象工廠模式如何選擇開(kāi)始的時(shí)候,可以選擇工廠方法模式,因?yàn)樗芎?jiǎn)單只需要繼承,并實(shí)現(xiàn)工廠方法即可。

問(wèn)題:在上一篇 python設(shè)計(jì)模式:工廠方法模式我們嘗試使用工廠方法創(chuàng)建了披薩店,現(xiàn)在為了保證披薩加盟店也能有良好的聲譽(yù),我們需要統(tǒng)一原材料,這個(gè)該如何做呢?

為了確保每家加盟店都是用高質(zhì)量的原材料,我們打算建造一加原材料工廠,并將原材料運(yùn)送到各個(gè)加盟店。每個(gè)加盟店會(huì)對(duì)原材料有不同的需求,這里我們就可以用上上一篇介紹的工廠方法模式了。

首先,建造原料工廠

然后建造區(qū)域的原料工廠(繼承自原料工廠)

在區(qū)域的原料工廠中實(shí)現(xiàn)原料的創(chuàng)建方法。

將原料工廠組合起來(lái),加入到 PizzaStore(上一篇中由工廠方法實(shí)現(xiàn))代碼中。

按照這個(gè)思路,我們先創(chuàng)建原料工廠

創(chuàng)建原料工廠

創(chuàng)建原料工廠的實(shí)現(xiàn)代碼如下:

# 原料
class FreshClams:

    def __str__(self):
        return "Fresh Clams"

class MarinaraSauce:

    def __str__(self):
        return "Marinara Sauce"

class ThickCrustDough:

    def __str__(self):
        return "Thick Crust Dough"

class ReggianoCheese:

    def __str__(self):
        return "Reggiano Cheese"

class SlicedPepperoni:

    def __str__(self):
        return "Sliced Pepperoni"

class Garlic:

    def __str__(self):
        return "Garlic"

class Onion:

    def __str__(self):
        return "Onion"

class RedPepper:

    def __str__(self):
        return "Red Pepper"

# 披薩店原料工廠
class PizzaIngredientFactory:

    """
    定義原料工廠
    """

    def create_dough(self):
        raise NotImplementedError()

    def create_sauce(self):
        raise NotImplementedError()

    def create_cheese(self):
        raise NotImplementedError()

    def create_pepperoni(self):
        raise NotImplementedError()

    def create_clam(self):
        raise NotImplementedError()

    def create_veggies(self):
        raise NotImplementedError()

在這個(gè)工廠中,每個(gè)原料都是一個(gè)方法,原料的實(shí)現(xiàn)需要在具體的原料工廠中實(shí)現(xiàn)。
這里每個(gè)原料方法沒(méi)有做任何工作,只是拋出了NotImplementedError 這樣做是為了強(qiáng)制子類(lèi)重新實(shí)現(xiàn)相應(yīng)的方法,如果不重新實(shí)現(xiàn)用到時(shí)就會(huì)拋出 NotImplementedError。

當(dāng)然也可以把 PizzaIngredientFactory 的 metaclass 設(shè)置成 abc.ABCMeta 這樣的話,這個(gè)類(lèi)就是真正的抽象基類(lèi)。

創(chuàng)建紐約原料工廠
class NYPizzaIngredientFactory(PizzaIngredientFactory):
    def create_dough(self):
        print("Tossing %s" % ThickCrustDough())
        return ThickCrustDough()

    def create_sauce(self):
        print("Adding %s..." % MarinaraSauce())
        return MarinaraSauce()

    def create_cheese(self):
        print("Adding %s..." % ReggianoCheese())
        return ReggianoCheese()

    def create_pepperoni(self):
        print("Adding %s..." % SlicedPepperoni())
        return SlicedPepperoni()

    def create_clam(self):
        print("Adding %s..." % FreshClams())
        return FreshClams()

    def create_veggies(self):
        # 蔬菜可能有多種,這里使用列表
        veggies = [Garlic(), Onion(), RedPepper()]
        for veggie in veggies:
            print("  %s" % veggie)
        return veggies

對(duì)于原料家族的每一種原料,我們都提供了原料的紐約版本。

重做 Pizza 類(lèi)
class Pizza:
    
    name = None
    dough = None
    sauce = None
    cheese = None
    veggies = []
    pepperoni = None
    clam = None

    def prepare(self):
        raise NotImplementedError()

    def bake(self):
        print("Bake for 25 minutes at 350")

    def cut(self):
        print("Cutting the pizza into diagonal slices")

    def box(self):
        print("Place pizza in official PizzaStore box")

    def __str__(self):
        return self.name

上述代碼和工廠方法的代碼相比,只是把 prepare() 方法抽象出來(lái),需要相應(yīng)的 具體的 pizza 類(lèi)來(lái)實(shí)現(xiàn) prepare()。

實(shí)現(xiàn) 芝加哥芝士披薩
class NYStyleCheesePizza(Pizza):

    def prepare(self):
        dough = self.ingredient_factory.create_dough()
        sauce = self.ingredient_factory.create_sauce()
        cheese = self.ingredient_factory.create_cheese()
        clam = self.ingredient_factory.create_clam()
        veggies = self.ingredient_factory.create_veggies()

從上述代碼可以發(fā)現(xiàn),Pizza 的原料也是從原料工廠直接獲取,現(xiàn)在我們控制了原料。

現(xiàn)在,Pizza 類(lèi)不需要關(guān)心原料,只需要負(fù)責(zé)制作 pizza 就好。Pizza 和原料被解耦。

重新實(shí)現(xiàn) PizzaStore
class PizzaStore:
    
    # 需要聲明原料工廠
    ingredient_factory = None

    def create_pizza(self, pizza_type):
        # 每個(gè)需要子類(lèi)實(shí)現(xiàn)的方法都會(huì)拋出NotImplementedError
        # 我們也可以把 PizzaStore 的 metaclass 設(shè)置成 abc.ABCMeta
        # 這樣的話,這個(gè)類(lèi)就是真正的抽象基類(lèi)
        raise NotImplementedError()

    def order_pizza(self, pizza_type):  # 現(xiàn)在把 pizza 的類(lèi)型傳入 order_pizza()

        pizza = self.create_pizza(pizza_type)

        #  一旦我們有了一個(gè) pizza,需要做一些準(zhǔn)備(搟面皮、加佐料),然后烘烤、切片、裝盒
        pizza.prepare()
        pizza.bake()
        pizza.cut()
        pizza.box()
        return pizza

class NYStylePizzStore(PizzaStore):
    
    # 將需要用到的原料工廠賦值給變量 ingredient_factory
    ingredient_factory = NYPizzaIngredientFactory()

    def create_pizza(self, pizza_type):
        # 根據(jù) pizza 類(lèi)型,我們實(shí)例化正確的具體類(lèi),然后將其賦值給 pizza 實(shí)例變量
        if pizza_type == "cheese":
            pizza = NYStyleCheesePizza("NY Style Sauce and Cheese Pizza",
                                       self.ingredient_factory)
        elif pizza_type == "clam":
            pizza = NYStyleClamPizza("NY Style Clam Pizza",
                                     self.ingredient_factory)
        return pizza

通過(guò)上述代碼可以看到我們做了以下工作:

引入了新類(lèi)型的工廠(抽象工廠)來(lái)創(chuàng)建原料家族

通過(guò)抽象工廠提供的接口,我們創(chuàng)建了原料家族。

我們的原料代碼從實(shí)際的 Pizza 工廠中成功解耦,可以應(yīng)用到不同地方,響應(yīng)的,我們可以方便的替換原料工廠來(lái)生產(chǎn)不同的 pizza。

來(lái)看下下單的代碼
def main():
    nystore = NYStylePizzStore()
    pizza = nystore.order_pizza("cheese")
    print("*" * 10)
    print("goodspeed ordered a %s" % pizza)
    print("*" * 10)

和工廠方法的代碼相比,沒(méi)有任何改變。

[源碼參考python-design-patter-abstract-factory.py](https://gist.github.com/gusibi/5e0797f5458678322486f999ca87a180)

抽象工廠模式

抽象工廠模式提供一個(gè)接口,用于創(chuàng)建相關(guān)或依賴(lài)對(duì)象的家族,而不需要指定具體類(lèi)。

也就是說(shuō),抽象工廠允許客戶(hù)使用抽象的接口來(lái)創(chuàng)建一組相關(guān)的產(chǎn)品,而不需要知道實(shí)際產(chǎn)出的具體產(chǎn)品是什么,這樣依賴(lài),客戶(hù)就從具體產(chǎn)品中被解耦。

概括來(lái)說(shuō)就是,抽象工廠是邏輯上的一組工廠方法,每個(gè)工廠方法各司其職,負(fù)責(zé)生產(chǎn)不同種類(lèi)的對(duì)象。

我們來(lái)看下 抽象工廠模式 的類(lèi)圖:

抽象工廠在 django_factory 中應(yīng)用比較多,有興趣的可以看下源碼。

抽象工廠模式 和 工廠方法模式 的比較

抽象工廠模式 和 工廠方法模式 都是負(fù)責(zé)創(chuàng)建對(duì)象,但

工廠方法模式使用的是繼承

抽象工廠模式使用的是對(duì)象的組合

這也就意味著利用工廠方法創(chuàng)建對(duì)象需要擴(kuò)展一個(gè)類(lèi),并覆蓋它的工廠方法(負(fù)責(zé)將客戶(hù)從具體類(lèi)中解耦)。
抽象工廠提供一個(gè)用來(lái)創(chuàng)建產(chǎn)品家族的抽象類(lèi)型,這個(gè)類(lèi)型的子類(lèi)定義了產(chǎn)品被產(chǎn)生的方法。要想使用這個(gè)工廠(NYPizzaIngredientFactory),必須先實(shí)例化它(ingredient_factory = NYPizzaIngredientFactory()),然后將它傳入一些針對(duì)抽象類(lèi)型所寫(xiě)的代碼中(也做到了將客戶(hù)從具體產(chǎn)品中解耦),同時(shí)還把一群相關(guān)的產(chǎn)品集合起來(lái)。

工廠方法模式和抽象工廠模式如何選擇

開(kāi)始的時(shí)候,可以選擇工廠方法模式,因?yàn)樗芎?jiǎn)單(只需要繼承,并實(shí)現(xiàn)工廠方法即可)。如果后來(lái)發(fā)現(xiàn)應(yīng)用需要用到多個(gè)工廠方法,那么是時(shí)候使用抽象工廠模式了,它可以把相關(guān)的工廠方法組合起來(lái)。

抽象工廠模式優(yōu)點(diǎn)和缺點(diǎn) 優(yōu)點(diǎn)

可以將客戶(hù)從具體產(chǎn)品中解耦

抽象工廠可以讓對(duì)象創(chuàng)建更容易被追蹤

同時(shí)將對(duì)象創(chuàng)建與使用解耦

也可以?xún)?yōu)化內(nèi)存占用提升應(yīng)用性能

缺點(diǎn)

因?yàn)槌橄蠊S是將一組相關(guān)的產(chǎn)品集合起來(lái),如果需要擴(kuò)展這組產(chǎn)品,就需要改變接口,而改變接口則意味著需要改變每個(gè)子類(lèi)的接口

參考鏈接

python設(shè)計(jì)模式:工廠方法模式

python-design-patter-abstract-factory.py https://gist.github.com/gusibi/5e0797f5458678322486f999ca87a180


最后,感謝女朋友支持。

歡迎關(guān)注(April_Louisa) 請(qǐng)我喝芬達(dá)

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/40974.html

相關(guān)文章

  • 設(shè)計(jì)模式抽象工廠模式

    摘要:所謂的產(chǎn)品族,一般或多或少的都存在一定的關(guān)聯(lián),抽象工廠模式就可以在類(lèi)內(nèi)部對(duì)產(chǎn)品族的關(guān)聯(lián)關(guān)系進(jìn)行定義和描述,而不必專(zhuān)門(mén)引入一個(gè)新的類(lèi)來(lái)進(jìn)行管理。 0x01.定義與類(lèi)型 定義:抽象工廠模式提供一個(gè)創(chuàng)建一系列相關(guān)或相互依賴(lài)對(duì)象的接口 無(wú)需指定它們具體的類(lèi) 類(lèi)型:創(chuàng)建型 UML showImg(https://segmentfault.com/img/bVbtBp1?w=800&h=862...

    Acceml 評(píng)論0 收藏0
  • Python實(shí)現(xiàn)設(shè)計(jì)模式——工廠模式

    摘要:本文會(huì)用實(shí)現(xiàn)三種工廠模式的簡(jiǎn)單例子,所有代碼都托管在上。工廠方法模式繼承了簡(jiǎn)單工廠模式的優(yōu)點(diǎn)又有所改進(jìn),其不再通過(guò)一個(gè)工廠類(lèi)來(lái)負(fù)責(zé)所有產(chǎn)品的創(chuàng)建,而是將具體創(chuàng)建工作交給相應(yīng)的子類(lèi)去做,這使得工廠方法模式可以允許系統(tǒng)能夠更高效的擴(kuò)展。 前言 工廠模式,顧名思義就是我們可以通過(guò)一個(gè)指定的工廠獲得需要的產(chǎn)品,在設(shè)計(jì)模式中主要用于抽象對(duì)象的創(chuàng)建過(guò)程,讓用戶(hù)可以指定自己想要的對(duì)象而不必關(guān)心對(duì)象的...

    CrazyCodes 評(píng)論0 收藏0
  • python設(shè)計(jì)模式-工廠方法模式

    摘要:工廠方法模式可以幫助我們將產(chǎn)品的實(shí)現(xiàn)從使用中解耦。應(yīng)用中使用工廠模式的例子的模塊使用工廠方法模式來(lái)創(chuàng)建表單字段。也使用到了工廠方法模式。中不同數(shù)據(jù)庫(kù)連接部分也用到了工廠方法模式。 題目:假設(shè)你有一個(gè) pizza 店,功能包括下訂單、做 pizza,你的代碼會(huì)如何寫(xiě)呢? def order_pizza(): pizza = Pizza() pizza.prepare() ...

    pubdreamcc 評(píng)論0 收藏0
  • 設(shè)計(jì)模式工廠方法模式

    摘要:通過(guò)工廠方法模式的類(lèi)圖可以看到,工廠方法模式有四個(gè)要素工廠接口工廠接口是工廠方法模式的核心,與調(diào)用者直接交互用來(lái)提供產(chǎn)品。使用場(chǎng)景創(chuàng)建類(lèi)模式,在任何需要生成復(fù)雜對(duì)象的地方,都可以使用工廠方法模式。 0x01.定義與類(lèi)型 定義:定義一個(gè)創(chuàng)建對(duì)象的接口,但讓實(shí)現(xiàn)這個(gè)接口的類(lèi)來(lái)決定實(shí)例化那個(gè)類(lèi),工廠方法讓類(lèi)的實(shí)例化推遲到子類(lèi)中進(jìn)行 類(lèi)型:創(chuàng)建型 uml類(lèi)圖 showImg(https:/...

    geekidentity 評(píng)論0 收藏0
  • python之單例模式工廠模式

    摘要:在工廠方法模式中,我們會(huì)遇到一個(gè)問(wèn)題,當(dāng)產(chǎn)品非常多時(shí),繼續(xù)使用工廠方法模式會(huì)產(chǎn)生非常多的工廠類(lèi)。從簡(jiǎn)單工廠模式到抽象工廠模式,我們都是在用后一種模式解決前一種模式的缺陷,都是在最大程度降低代碼的耦合性。 單例模式 所謂單例模式,也就是說(shuō)不管什么時(shí)候我們要確保只有一個(gè)對(duì)象實(shí)例存在。很多情況下,整個(gè)系統(tǒng)中只需要存在一個(gè)對(duì)象,所有的信息都從這個(gè)對(duì)象獲取,比如系統(tǒng)的配置對(duì)象,或者是線程池。這些...

    jayce 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<