有時為了給某個物件而不是給整個類新增乙個功能
,使用繼承機制
是新增功能的乙個有效途徑,但是不夠靈活
,使用者不能控制對元件加邊框的方式和時機,並且會導致子類膨脹。一種較為靈活的方式就是將元件嵌入
另乙個物件中,這個嵌入的物件叫做裝飾。
裝飾模式
:動態
地給乙個物件增加
一些額外的職責
。就擴充套件功能
而言,裝飾模式提供了一種比使用子類更加靈活
的替代方案。以對客戶透明的方式動態地給乙個物件附加上更多的責任 可以在不需要建立更多子類的情況下,讓物件的功能得以擴充套件
裝飾(decorator)模式的定義
:指在不改變現有物件結構的情況下,動態地給該物件增加一些職責(即增加其額外功能)的模式,它屬於物件結構型模式。
裝飾(decorator)模式的主要優點
有:
採用裝飾模式擴充套件物件的功能比採用繼承方式更加靈活。
可以設計出多個不同的具體裝飾類,創造出多個不同行為的組合。
其主要缺點
是:裝飾模式增加了許多子類,如果過度使用會使程式變得很複雜。
通常情況下,擴充套件乙個類的功能會使用繼承方式來實現。但繼承具有靜態特徵,耦合度高,並且隨著擴充套件功能的增多,子類會很膨脹。如果使用組合關係來建立乙個包裝物件(即裝飾物件)來包裹真實物件,並在保持真實物件的類結構不變的前提下,為其提供額外的功能,這就是裝飾模式的目標。下面來分析其基本結構和實現方法。
模式的結構
裝飾模式主要包含以下角色。
抽象構件(component)角色
:定義乙個抽象介面以規範準備接收附加責任的物件。
具體構件(concrete component)角色
:實現抽象構件,通過裝飾角色為其新增一些職責。
抽象裝飾(decorator)角色
:繼承抽象構件,幷包含具體構件的例項,可以通過其子類擴充套件具體構件的功能。
具體裝飾(concretedecorator)角色
:實現抽象裝飾的相關方法,並給具體構件物件新增附加的責任。
#又提到了那個快餐點餐系統,不過今天我們只以其中的乙個類作為主角:飲料類。首先,回憶下飲料類:
class
beverage()
: name =
"" price =
0.0type
="beverage"
defgetprice
(self)
:return self.price
defsetprice
(self, price)
: self.price = price
defgetname
(self)
:return self.name
class
coke
(beverage)
:def
__init__
(self)
: self.name =
"coke"
self.price =
4.0class
milk
(beverage)
:def
__init__
(self)
: self.name =
"milk"
self.price =
5.0#除了基本配置,快餐店賣可樂時,可以選擇加冰,如果加冰的話,要在原價上加0.3元;
# 賣牛奶時,可以選擇加糖,如果加糖的話,要原價上加0.5元。怎麼解決這樣的問題?
# 可以選擇裝飾器模式來解決這一類的問題。首先,定義裝飾器類:
class
drinkdecorator()
:def
getname
(self)
:pass
defgetprice
(self)
:pass
class
icedecorator
(drinkdecorator)
:def
__init__
(self, beverage)
: self.beverage = beverage
defgetname
(self)
:return self.beverage.getname()+
" +ice"
defgetprice
(self)
:return self.beverage.getprice()+
0.3class
sugardecorator
(drinkdecorator)
:def
__init__
(self, beverage)
: self.beverage = beverage
defgetname
(self)
:return self.beverage.getname()+
" +sugar"
defgetprice
(self)
:return self.beverage.getprice()+
0.5#構建好裝飾器後,在具體的業務場景中,就可以與飲料類進行關聯。以可樂+冰為例,示例業務場景如下:
if __name__==
"__main__"
: coke_cola=coke(
)print
("name:%s"
%coke_cola.getname())
print
("price:%s"
%coke_cola.getprice())
ice_coke=icedecorator(coke_cola)
print
("name:%s"
% ice_coke.getname())
print
("price:%s"
% ice_coke.getprice(
))
列印結果:
name:coke
price:4.0
name:coke +ice
price:4.3
在不影響其他物件的情況下,以動態、透明的方式給單個物件新增職責 當不能採用繼承的方式對系統進行擴充套件或者採用繼承不利於系統擴充套件和維護時可以使用裝飾模式
Python設計模式 裝飾器模式
基於3.5.2,如下 coding utf 8 裝飾器模式 class beverage name price 0.0 type beverage defgetprice self return self.price defsetprice self,price self.price price d...
python設計模式 裝飾器模式
裝飾類方法 裝飾類物件方法 裝飾類functools 方法 類內建的裝飾器 python基礎 裝飾器高階 這篇部落格是學習各個方面的裝飾器,諸如裝飾方法 類 類方法 裝飾器庫functools 裝飾函式的裝飾器,就是為某個函式的執行前後,或者函式引數,進而對被裝飾的函式產生影響作用 def meth...
Python設計模式 裝飾器模式
裝飾器模式,動態地給乙個物件新增一些額外的職責,就增加功能來說,裝飾器模式比生成子類更為靈活。示例 coding utf 8 裝飾器模式 class beverage name price 0.0 type beverage def getprice self return self.price d...