裝飾者模式定義:不通過派生類增改類屬性動作,而是通過模式設計動態的達到這種效果,而且比繼承更方便靈活減少程序的復雜性。
舉例
汪峰打造冠軍團隊。
首先團隊類為空,經過汪峰不斷的努力,為團隊爭取學員,也為團隊隊員打造合適的平台,讓其發揮。
團隊不斷的變強,變完整,是由裝飾者,根據不同的需求,給基類進行增改,一致最後贏得你的贊同,滿足你的需求。
實現裝配器模式的類圖:
戰隊組建代碼
? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71//汪峰戰隊
abstract
class
WangFengTeam
{
//執行策劃命令
abstract
public
void
Acrion();
}
//學員
class
Student : WangFengTeam
{
// Methods
override
public
void
Acrion()
{
Console.WriteLine(
"汪峰團隊學員情況:"
);
}
}
// 戰隊總策劃
abstract
class
Direct : WangFengTeam
{
//汪峰戰隊
protected
WangFengTeam team;
// 策劃活動
public
void
SetComponent(WangFengTeam team)
{
this
.team = team;
}
//執行策劃
override
public
void
Acrion()
{
if
(team !=
null
)
{
team.Acrion();
}
}
}
//男孩唱狂放型的,構建一個組合。
class
BoyTeam : Direct
{
// 組合名稱
public
string
teamName=
"鋒利的Jquery"
;
//具體策劃
override
public
void
Acrion()
{
base
.Acrion();
Console.WriteLine(
"我是汪峰團隊,狂放型的。"
);
}
}
//女孩唱婉約型的,來個模特表演
class
GrilTeam : Direct
{
//具體策劃
override
public
void
Acrion()
{
base
.Acrion();
Console.WriteLine(
"我是汪峰團隊,婉約型的。"
);
//模特表演
show();
}
public
void
show()
{
Console.WriteLine(
"婉約型,走秀"
);
}
}
客戶端代碼:
? 1 2 3 4 5 6 7 8 9 10 11 12 13public
static
void
Main()
{
Student team =
new
Student();
BoyTeam boy =
new
BoyTeam();
GrilTeam girl =
new
GrilTeam();
//團隊男孩裝飾
boy.SetComponent(team);
//團隊女孩裝飾
girl.SetComponent(boy);
girl.Acrion();
Console.Read();
}
裝飾者模式的優缺點
看完裝飾者模式的詳細介紹之後,我們繼續分析下它的優缺點。
優點:
缺點:
裝飾者模式會導致設計中出現許多小對象,如果過度使用,會讓程序變的更復雜。並且更多的對象會是的差錯變得困難,特別是這些對象看上去都很像。
使用場景
下面讓我們看看裝飾者模式具體在哪些情況下使用,在以下情況下應當使用裝飾者模式:
需要擴展一個類的功能或給一個類增加附加責任。
需要動態地給一個對象增加功能,這些功能可以再動態地撤銷。
需要增加由一些基本功能的排列組合而產生的非常大量的功能
.Net中裝飾者模式的實現
在.Net 類庫中也有裝飾者模式的實現,該類就是System.IO.Stream,下面看看Stream類結構:
BufferedStream、CryptoStream和GZipStream其實就是兩個具體裝飾類,這裡的裝飾者模式省略了抽象裝飾角色(Decorator)。下面演示下客戶端如何動態地為MemoryStream動態增加功能的。
? 1 2 3 4 5 6 7MemoryStream memoryStream =
new
MemoryStream(
new
byte
[] {95,96,97,98,99});
// 擴展緩沖的功能
BufferedStream buffStream =
new
BufferedStream(memoryStream);
// 添加加密的功能
CryptoStream cryptoStream =
new
CryptoStream(memoryStream,
new
AesManaged().CreateEncryptor(),CryptoStreamMode.Write);
// 添加壓縮功能
GZipStream gzipStream =
new
GZipStream(memoryStream, CompressionMode.Compress,
true
);
總結
到這裡,裝飾者模式的介紹就結束了,裝飾者模式采用對象組合而非繼承的方式實現了再運行時動態地擴展對象功能的能力,而且可以根據需要擴展多個功能,避免了單獨使用繼承帶來的 ”靈活性差“和”多子類衍生問題“。同時它很好地符合面向對象設計原則中 ”優先使用對象組合而非繼承“和”開放-封閉“原則。