python設(shè)計模式之抽象工廠模式詳解
抽象工廠模式(Abstract Factory Pattern):屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對象的最佳方式。在抽象工廠模式中,接口是負(fù)責(zé)創(chuàng)建一個相關(guān)對象的工廠,不需要顯式指定它們的類,每個生成的工廠都能按照工廠模式提供對象。
意圖: 提供一個創(chuàng)建一系列相關(guān)或相互依賴對象的接口,而無需指定它們具體的類。
主要解決: 主要解決接口選擇的問題。
何時使用: 系統(tǒng)的產(chǎn)品有多于一個的產(chǎn)品族,而系統(tǒng)只消費其中某一族的產(chǎn)品。
如何解決: 在一個產(chǎn)品族里面,定義多個產(chǎn)品。
關(guān)鍵代碼: 在一個工廠里聚合多個同類產(chǎn)品。
優(yōu)點: 當(dāng)一個產(chǎn)品族中的多個對象被設(shè)計成一起工作時,它能保證客戶端始終只使用同一個產(chǎn)品族中的對象。抽象工廠模式相較于工廠模式,劃分更加明確清晰,面對復(fù)雜的生產(chǎn)任務(wù),管理和生產(chǎn)性能會更加高效。
缺點: 產(chǎn)品族擴(kuò)展非常困難,要增加一整個系列的某一產(chǎn)品。
注意事項: 產(chǎn)品族難擴(kuò)展,產(chǎn)品等級易擴(kuò)展。
應(yīng)用實例: 對于一個生產(chǎn)水果的工廠,工廠模式主要針對一種水果創(chuàng)建一個涵蓋與該水果相關(guān)所有業(yè)務(wù)的工廠(例如:葡萄的運輸、保存、加工、包裝、售賣等相關(guān)業(yè)務(wù)全部被該工廠承包);而抽象工廠模式主要針對生產(chǎn)其中的某一環(huán)節(jié)進(jìn)行創(chuàng)建相應(yīng)的工廠(例如:運輸工廠負(fù)責(zé)管理所有水果的運輸,售賣工廠負(fù)責(zé)管理所有水果的價格和售賣,庫存工廠負(fù)責(zé)管理所有水果的庫存計數(shù)等)。
那我們來一起使用抽象工廠模式,構(gòu)建一個購買水果的收銀小項目吧!(づ。◕ᴗᴗ◕。)づ
實現(xiàn)的思路:
項目的主體包含6個部分:消費者(買水果的人),水果工廠(賣水果的人),水果工廠旗下的子工廠(品種工廠、價格工廠、包裝工廠、稱重工廠消費者主要向水果工廠傳達(dá)“購買需求”的相關(guān)信息(水果的種類、包裝、重量等…);水果工廠主要針對消費者的不同“購買需求”將任務(wù)分派給子工廠進(jìn)行執(zhí)行;品種工廠負(fù)責(zé)管理水果的種類,價格工廠負(fù)責(zé)管理水果的價格,稱重工廠負(fù)責(zé)水果的稱重,包裝工廠負(fù)責(zé)水果的包裝方式。
項目的UML用例圖如下:
實現(xiàn)的代碼如下:
class FruitClass: # 品種工廠 def get_name(self, name_index): if name_index == 0: name_object = OrangeClass() elif name_index == 1: name_object = Hami_MelonClass() elif name_index == 2: name_object = GrapeClass() else: name_object = None return name_object class OrangeClass: # 橘子類 def __init__(self): self.name = "橘子" def print_name(self): print("您購買的水果為:%s" % self.name) class Hami_MelonClass: # 哈密瓜類 def __init__(self): self.name = "哈密瓜" def print_name(self): print("您購買的水果為:%s" % self.name) class GrapeClass: # 葡萄類 def __init__(self): self.name = "葡萄" def print_name(self): print("您購買的水果為:%s" % self.name) class FruitWeight: # 稱重工廠 def __init__(self, weight): self.weight = float(weight) def print_weight(self): print("該水果的重量為:%.2f千克" % self.weight) class FruitPrice: # 價格工廠 def get_price(self, name_index, variety): if name_index == 0: price_object = OrangePrice(variety) elif name_index == 1: price_object = Hami_MelonPrice() elif name_index == 2: price_object = GrapePrice() else: price_object = None return price_object class OrangePrice: # 橘子價格類 def __init__(self, variety): self.variety = variety if self.variety == 1: self.price = 8.5 else: self.price = 11.0 def print_price(self): print("該水果的單價為:%.2f元/千克" % self.price) class Hami_MelonPrice: # 哈密瓜價格類 def __init__(self): self.price = 24.3 def print_price(self): print("該水果的價格為:%.2f元/千克" % self.price) class GrapePrice: # 葡萄價格類 def __init__(self): self.price = 16.2 def print_price(self): print("該水果的價格為:%.2f元/千克" % self.price) return self.price class FruitPack: # 包裝工廠 def __init__(self, pack): if pack == 1: self.pack = "散稱" else: self.pack = "盒裝" def print_pack(self): print("該水果的打包方式為:%s" % self.pack) class FruitFactory: def __init__(self, name_index, weight, variety, pack): # 任務(wù)的分配,品種、重量、價格、包裝方式 self.name_object = FruitClass().get_name(name_index) self.weight_object = FruitWeight(weight) self.price_object = FruitPrice().get_price(name_index, variety) self.pack_object = FruitPack(pack) def print_purchase(self): # 計算購買的金額 money = self.price_object.price * self.weight_object.weight print("需要支付的金額共計為:%.2f元" % money) def show_info(self): # 展示最終的購買信息 self.name_object.print_name() self.weight_object.print_weight() self.price_object.print_price() self.pack_object.print_pack() self.print_purchase() print("-*-" * 20) class Consumer: # 消費者類 def __init__(self): print("-*-" * 20) # 輸入原始的“購買需求”信息 self.name = input("請輸入你要購買的水果名稱:0.橘子 1.哈密瓜 2.葡萄\n") self.weight = input("請輸入你要購買水果的重量(kg):\n") self.variety = input("如果您購買橘子,我們有2種橘子:0.不買橘子 1.甘橘 2.砂糖橘\n") self.pack = input("請您選擇該水果的包裝方式:1.散稱 2.盒裝\n") print("-*-" * 20) def request(self): # 返回相關(guān)的購買信息 return self.name, self.weight, self.variety, self.pack if __name__ == '__main__': # 創(chuàng)建顧客 buyer = Consumer() # 拿到顧客的購買信息 buy_info = buyer.request() # 使用水果工廠,傳達(dá)指令至旗下的子工廠并執(zhí)行購買操作 buy_res = FruitFactory(int(buy_info[0]), int(buy_info[1]), int(buy_info[2]), int(buy_info[3])) # 購買信息的展示 buy_res.show_info()
相關(guān)的測試用例:
本文關(guān)于設(shè)計模式的講解思想,參考鏈接:抽象工廠模式
如果有對python類的創(chuàng)建和繼承等用法還不熟悉的小伙伴,請參考這篇博客: python類的繼承
到此這篇關(guān)于python設(shè)計模式之抽象工廠模式的文章就介紹到這了,更多相關(guān)python抽象工廠模式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python中byte字符串轉(zhuǎn)string的實現(xiàn)
本文主要介紹了Python中byte字符串轉(zhuǎn)string的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07基于Python利用Faker批量測試數(shù)據(jù)
這篇文章主要介紹了基于Python利用Faker批量測試數(shù)據(jù)。測試過程中,經(jīng)常需要批量去造數(shù)據(jù),方法有很多,最簡單方便的應(yīng)該是使用python?的一個三方庫Faker。下面我們就來看看三方庫Faker如何批量測試數(shù)據(jù),需要的朋友可以參考一下2022-03-03Python之lambda匿名函數(shù)及map和filter的用法
今天小編就為大家分享一篇關(guān)于Python之lambda匿名函數(shù)及map和filter的用法,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-03-03Python結(jié)合spaCy?進(jìn)行簡易自然語言處理
這篇文章主要為大家介紹了Python結(jié)合spaCy進(jìn)行簡易自然語言處理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06