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元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

