裝飾模式(python版)
目錄
什麼是裝飾模式
裝飾模式(Decorator),動態的給一個物件新增一些格外的職責,就增加功能來說,裝飾模式比生成子類更靈活
裝飾模式UML圖
Component是定義一個物件介面,可以給這些物件動態的新增職責。ConcreteComponent是定義了一個具體的物件,也可以給這個物件新增一些職責。Decorator,裝飾抽象類,繼承了Component,從外類來擴充套件Component類的功能,但對於Component來說,是無需知道Decorator的存在的。治癒ConcreteDecorator就是具體的裝飾物件,起到給Component新增職責的功能。
裝飾模式的python實現
下面考慮《大話設計模式》中的例子:
題目:
寫一個可以給人搭配不同的服飾的系統,可以換各種各樣的衣服褲子的個人形象系統(簡單點的,用控制檯實現)
題目分析:
利用開放封閉原則(對於擴充套件是開放的(Open for extension),對於更改是封閉的(Closeed for modification))。無論模組是多麼的’封閉’,都會存在一些無法對之封閉的變換。既然不可能完全封閉,設計人員必須對於他設計的模組應該對哪種變化封閉做出選擇。必須先猜測出最有可能發生的變化種類,然後構造抽象來隔離那些變化。
裝飾模式是利用SetComponent來對物件進行包裝的。這樣每個裝飾物件的實現就和如何使用這個物件分離開了,每個裝飾物件值關心自己的功能,不需要關心如何被新增到物件鏈當中。
實現程式碼結構圖
程式碼實現
Person類
class Person():
def __init__(self,name='',sex='男'):
self.name = name #person的姓名
self.sex = sex #性別
self.decoration = [cloth1,cloth8] #穿的衣服的list
def put_on(self,clothes) :
genre = clothes.genre
priority = clothes.priority
self.del_the_same(genre,priority,1) #穿上先要脫掉已經穿上的和要穿的衣服外面的
self.decoration.append(clothes) #穿上衣服
def put_off(self,clothes):
genre = clothes.genre
priority = clothes.priority
self.del_the_same(genre,priority,0) #脫掉衣服
def del_the_same(self,genre,priority,flag):
i = 0
while 1:
try:
c = self.decoration[i]
except:
break
priorityF0 = c.priority == priority and flag == 0
priorityF1 = c.priority >= priority and flag == 1
if c.genre == genre and (priorityF0 or priorityF1):
del self.decoration[i]
else:
i += 1
def show_clothes(self):
string = self.name+'穿了 '
for c in self.decoration:
string += c.name + ' ,'
return string[:-2]
clothes類
class clothes():
def __init__(self,id=0,name='',priority=0,genre=''):
self.name = name #衣服的名字
self.id = id #衣服的id
self.genre = genre #衣服的型別
self.priority = priority #衣服穿的優先順序,優先順序小的穿在下面
衣櫃
cloth1 = clothes(id = 1,name = "背心",priority = 0,genre = "上衣")
cloth2 = clothes(id = 2,name = "坎肩",priority = 0,genre = "上衣")
cloth3 = clothes(id = 3,name = "襯衫",priority = 1,genre = "上衣")
cloth4 = clothes(id = 4,name = "西服",priority = 2,genre = "上衣")
cloth5 = clothes(id = 5,name = "領帶",priority = 2,genre = "配飾")
cloth6 = clothes(id = 6,name = "西褲",priority = 1,genre = "褲子")
cloth7 = clothes(id = 7,name = "七分褲",priority = 1,genre = "褲子")
cloth8 = clothes(id = 8,name = "短褲",priority = 1,genre = "褲子")
cloth9 = clothes(id = 9,name = "皮鞋",priority = 1,genre = "鞋")
cloth10 = clothes(id = 10,name = "休閒鞋",priority = 1,genre = "鞋")
cloth11 = clothes(id = 11,name = "涼鞋",priority = 1,genre = "鞋")
cloth12 = clothes(id = 12,name = "短襪",priority = 0,genre = "鞋")
cloth13 = clothes(id = 13,name = "長襪",priority = 0,genre = "鞋")
cloth14 = clothes(id = 14,name = "眼鏡",priority = 1,genre = "配飾")
客戶端示例
xc = Person(name = "小菜",sex = "男")
xc.put_on(cloth4)
xc.put_on(cloth1)
xc.put_on(cloth3)
xc.put_on(cloth10)
xc.put_on(cloth14)
xc.put_on(cloth6)
print unicode(xc.show_clothes(), "utf-8")
結果示例
E:\python>python Decoration.py
小菜穿了 背心 ,襯衫 ,休閒鞋 ,眼鏡 ,西褲
裝飾模式總結
裝飾模式是為已有的功能動態地新增更多功能的一種方式,當系統需要新功能的時候,是向舊的類中新增新的程式碼。這些新加的程式碼通常裝飾了原有的類的核心職責或主要行為,它們在主類中加入了新的欄位,新的方法和新的邏輯,從而增加了主類的複雜度,而這些新加入的東西僅僅是為了滿足一些只在某種特定情況下才會執行的特殊行為的需要。而裝飾模式卻提供了一個非常好的解決方案,它把每個要裝飾的功能放在單獨的類中,並讓這個類包裝它所要裝飾的物件。因此,當需要執行特殊行為是,客戶程式碼就可以在執行時根據需要選擇地,按順序地使用裝飾功能包裝了物件。