一、定義:
裝飾模式(Decorator):動(dòng)態(tài)地給一個(gè)對(duì)象添加一些額外的職責(zé),就增加功能來(lái)說(shuō),裝飾模式比生成子類更為靈活。
二、UML類圖:

三、基本代碼

class PRogram { static void Main(string[] args) { ConcreteComponent c = new ConcreteComponent(); ConcreteDecoratorA d1 = new ConcreteDecoratorA(); ConcreteDecoratorB d2 = new ConcreteDecoratorB(); d1.SetComponent(c); d2.SetComponent(d1); d2.Operation(); Console.Read(); } } abstract class Component { public abstract void Operation(); } class ConcreteComponent : Component { public override void Operation() { Console.WriteLine("具體對(duì)象的操作"); } } abstract class Decorator : Component { protected Component component; public void SetComponent(Component component) { this.component = component; } public override void Operation() { if (component != null) { component.Operation(); } } } class ConcreteDecoratorA : Decorator { private string addState; public override void Operation() { base.Operation(); addState = "new state"; Console.WriteLine("具體裝飾對(duì)象A的操作"); } } class ConcreteDecoratorB : Decorator { public override void Operation() { base.Operation(); AddBehavior(); Console.WriteLine("具體裝飾對(duì)象B的操作"); } private void AddBehavior() { Console.WriteLine("B 的穿衣"); } }
四、舉例說(shuō)明
在實(shí)際項(xiàng)目中,如果只有一個(gè)ConcreteComponent類而沒(méi)有抽象的Component類,那么Decorator類可以是ConcreteComponent類的一個(gè)子類。同樣道理,如果只有一個(gè)ConcreteDecorator類,那么就沒(méi)有必要建立一個(gè)單獨(dú)的Decorator類,可以把Decorator和ConcreteDecorator的責(zé)任合并成一個(gè)類。在下面實(shí)例中就是沒(méi)有抽象的Component類。實(shí)例的基本功能是完成一個(gè)穿衣功能:領(lǐng)帶垮褲大T恤的小菜。
類圖:

代碼:

class Program { static void Main(string[] args) { Person p = new Person("小菜"); TShirts ts = new TShirts(); BigTrouser bt = new BigTrouser(); Tie ti = new Tie(); ts.Decorate(p); bt.Decorate(ts); ti.Decorate(bt); ti.Show(); Console.Read(); } } class Person { public Person() { } private string name; public Person(string name) { this.name = name; } public virtual void Show() { Console.WriteLine("裝扮的{0}", name); } } class Finery : Person { protected Person component; public void Decorate(Person component) { this.component = component; } public override void Show() { if (component != null) { component.Show(); } } } class TShirts : Finery { public override void Show() { //base.Show(); Console.Write("大T恤"); base.Show(); } } class BigTrouser : Finery { public override void Show() { //base.Show(); Console.Write("垮褲"); base.Show(); } } class Tie : Finery { public override void Show() { //base.Show(); Console.Write("領(lǐng)帶"); base.Show(); } }
五、適用場(chǎng)景:
1、需要擴(kuò)展一個(gè)類的功能,或給一個(gè)類添加附加指責(zé)。
2、需要?jiǎng)討B(tài)的給一個(gè)對(duì)象添加功能,這些功能可以再動(dòng)態(tài)的撤銷。
3、需要增加由一些基本功能的排列組合而產(chǎn)生的非常大量的功能,從而使繼承關(guān)系變的不現(xiàn)實(shí)。
4、當(dāng)不能采用生成子類的方法進(jìn)行擴(kuò)充時(shí)。一種情況是,可能有大量獨(dú)立的擴(kuò)展,為支持每一種組合將產(chǎn)生大量的子類,使得子類數(shù)目呈爆炸性增長(zhǎng)。另一種情況可能是因?yàn)轭惗x被隱藏,或類定義不能用于生成子類。
六、優(yōu)缺點(diǎn):
優(yōu)點(diǎn):
1、Decorator模式與繼承關(guān)系的目的都是要擴(kuò)展對(duì)象的功能,但是Decorator可以提供比繼承更多的靈活性。
2、通過(guò)使用不同的具體裝飾類以及這些裝飾類的排列組合,設(shè)計(jì)師可以創(chuàng)造出很多不同行為的組合。
缺點(diǎn):
1、Decorator模式比繼承更加靈活機(jī)動(dòng)的特性,也同時(shí)意味著更加多的復(fù)雜性。
2、Decorator模式會(huì)導(dǎo)致設(shè)計(jì)中出現(xiàn)許多小類,如果過(guò)度使用,會(huì)使程序變得很復(fù)雜。
3、Decorator模式是針對(duì)抽象組件(Component)類型編程。但是,如果你要針對(duì)具體組件編程時(shí),就應(yīng)該重新思考你的應(yīng)用架構(gòu),以及裝飾者是否合適。當(dāng)然也可以改變Component接口,增加新的公開(kāi)的行為,實(shí)現(xiàn)“半透明”的裝飾者模式。在實(shí)際項(xiàng)目中要做出最佳選擇。
補(bǔ)充:
為了更好的理解裝飾者模式,此處添加一個(gè)在網(wǎng)上看到一個(gè)感覺(jué)非常不錯(cuò)的實(shí)例:

class Program { static void Main(string[] args) { Phone phone = new ApplePhone(); Sticker sticker = new Sticker(); accessories accessories = new Accessories(); sticker.SetPhone(phone); accessories.SetPhone(sticker); accessories.Print(); Console.Read(); } } public abstract class Phone { public abstract void Print(); } public class ApplePhone:Phone { public override void Print() { Console.WriteLine("開(kāi)始執(zhí)行具體的對(duì)象-蘋(píng)果手機(jī)"); } } public abstract class Decorator : Phone { private Phone phone; public void SetPhone(Phone phone) { this.phone = phone; } public override void Print() { if (phone != null) { phone.Print(); } } } public class Sticker : Decorator { public override void Print() { base.Print(); AddSticker(); } public void AddSticker() { Console.WriteLine("蘋(píng)果手機(jī)貼膜"); } } public class Accessories : Decorator { public override void Print() { base.Print(); AddAccessories(); } public void AddAccessories() { Console.WriteLine("蘋(píng)果手機(jī)掛件"); } }
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注