python實現建造者模式
前言
無論是在現實世界中還是在軟件系統中,都存在一些復雜的對象,它們擁有多個組成部分,如汽車,它包括車輪、方向盤、發送機等各種部件。而對于大多數用戶而言,無須知道這些部件的裝配細節,也幾乎不會使用單獨某個部件,而是使用一輛完整的汽車,可以通過建造者模式對其進行設計與描述, 建造者模式可以將部件和其組裝過程分開,一步一步創建一個復雜的對象。用戶只需要指定復雜對象的類型就可以得到該對象,而無須知道其內部的具體構造細節 .
?
?
介紹
建造者模式( Builder Pattern ) ? 又名生成器模式,是一種對象構建模式。它可以將復雜對象的建造過程抽象出來(抽象類別),使這個抽象過程的不同實現方法可以構造出不同表現(屬性)的對象。
建造者模式 ? 是一步一步創建一個復雜的對象,它允許用戶只通過指定復雜對象的類型和內容就可以構建它們,用戶不需要知道內部的具體構建細節。
主要解決: 主要解決在軟件系統中,有時候面臨著 "一個復雜對象"的創建工作,其通常由各個部分的子對象用一定的算法構成;由于需求的變化,這個復雜對象的各個部分經常面臨著劇烈的變化,但是將它們組合在一起的算法卻相對穩定。
何時使用: 一些基本部件不會變,而其組合經常變化的時候。
如何解決: 將變與不變分離開。
關鍵代碼: 建造者:創建和提供實例, 指揮者 :管理建造出來的實例的依賴關系。
應用實例: ?去肯德基,漢堡、可樂、薯條、炸雞翅等是不變的,而其組合是經常變化的,生成出所謂的"套餐"。
優點: ?1、建造者獨立,易擴展。 2、便于控制細節風險。
缺點: ?1、產品必須有共同點,范圍有限制。 2、如內部變化復雜,會有很多的建造類。
使用場景: ?1、需要生成的對象具有復雜的內部結構。 2、需要生成的對象內部屬性本身相互依賴。
注意事項: 與工廠模式的區別是:建造者模式更加關注與零件裝配的順序。
?
實例:KFC套餐
建造者模式可以用于描述KFC如何創建套餐:套餐是一個復雜對象,它一般包含主食(如漢堡、雞肉卷等)和飲料(如果汁、可樂等)等組成部分,不同的套餐有不同的組成部分,而KFC的服務員可以根據顧客的要求,一步一步裝配這些組成部分,構造一份完整的套餐,然后返回給顧客。
# 具體產品對象 class Menu: Menu_A = [] Menu_B = [] def set_MenuA(self,item): self.Menu_A.append(item) def set_MenuB(self,item): self.Menu_B.append(item) def get_MenuA(self): return self.Menu_A def get_MenuB(self): return self.Menu_B # Builder(抽象建造者) # 創建一個Product對象的各個部件指定的抽象接口。 class Product: product = Menu() def build_hanbao(self): pass def build_jiroujuan(self): pass def build_kele(self): pass def build_shutiao(self): pass # ConcreteBuilder(具體建造者) # 實現抽象接口,構建和裝配各個部件。 # 套餐A class product_A(Product): type = " A " def build_hanbao(self): self.hanbao = " 漢堡 " self.product.set_MenuA(self.hanbao) def build_kele(self): self.kele = " 可樂 " self.product.set_MenuA(self.kele) def getType(self): return type # 套餐B class product_B(Product): type = " B " def build_shutiao(self): self.shutiao = " 薯條 " self.product.set_MenuB(self.shutiao) def build_jiroujuan(self): self.jiroujuan = " 雞肉卷 " self.product.set_MenuB(self.jiroujuan) def build_kele(self): self.kele = " 可樂 " self.product.set_MenuB(self.kele) def getType(self): return type # Director(指揮者)
class Make: def __init__ (self): self.builder = None def build_product(self, builder): self.builder = builder print (builder.type) if builder.type == " A " : [step() for step in (builder.build_hanbao, builder.build_kele)] if builder.type == " B " : [step() for step in (builder.build_shutiao, builder.build_jiroujuan, builder.build_kele)] # 不同類型選擇 def validate_style(builders): global valid_input try : print ( ' 套餐A:漢堡、可樂 ' + ' \n ' ' 套裝B:薯條、雞肉卷、可樂 ' ) product_style = input( ' 請輸入您的選擇: ' ) builder = builders[product_style]() valid_input = True except KeyError as err: print ( ' Sorry, 沒有這個套餐,請重新選擇。 ' ) return (False, None) return (True, builder,product_style) # 主函數 def main(): builders = dict(A=product_A, B= product_B) valid_input = False while not valid_input: valid_input, builder,product_style = validate_style(builders) Waiter = Make() Waiter.build_product(builder) if product_style == " A " : print (builder.product.get_MenuA()) else : print (builder.product.get_MenuB()) if __name__ == " __main__ " : main()
輸出
套餐A:漢堡、可樂 套裝B:薯條、雞肉卷、可樂 請輸入您的選擇:A A [ ' 漢堡 ' , ' 可樂 ' ]
?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
