1、定義:編程
裝飾模式(Decorator):動態地給一個對象添加一些額外的職責,就增長功能來講,裝飾模式比生成子類更爲靈活。架構
簡單來講,裝飾模式很是相似於繼承,都能給對象添加一些額外的職責。若是須要靈活的添加一組有相對排列序列的功能,單純的繼承實現則顯得不是那麼優雅,裝飾模式能夠恰當的實現。ide
2、UML類圖:this
3、基本代碼spa
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("具體對象的操做"); } } 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("具體裝飾對象A的操做"); } } class ConcreteDecoratorB : Decorator { public override void Operation() { base.Operation(); AddBehavior(); Console.WriteLine("具體裝飾對象B的操做"); } private void AddBehavior() { Console.WriteLine("B 的穿衣"); } }
4、舉例說明設計
在實際項目中,若是隻有一個ConcreteComponent類而沒有抽象的Component類,那麼Decorator類能夠是ConcreteComponent類的一個子類。一樣道理,若是隻有一個ConcreteDecorator類,那麼就沒有必要創建一個單獨的Decorator類,能夠把Decorator和ConcreteDecorator的責任合併成一個類。在下面實例中就是沒有抽象的Component類。實例的基本功能是完成一個穿衣功能:領帶垮褲大T恤的小菜。code
類圖:component
代碼:對象
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("領帶"); base.Show(); } }
5、適用場景:blog
一、須要擴展一個類的功能,或給一個類添加附加指責。
二、須要動態的給一個對象添加功能,這些功能能夠再動態的撤銷。
三、須要增長由一些基本功能的排列組合而產生的很是大量的功能,從而使繼承關係變的不現實。
四、當不能採用生成子類的方法進行擴充時。一種狀況是,可能有大量獨立的擴展,爲支持每一種組合將產生大量的子類,使得子類數目呈爆炸性增加。另外一種狀況多是由於類定義被隱藏,或類定義不能用於生成子類。
6、優缺點:
優勢:
一、Decorator模式與繼承關係的目的都是要擴展對象的功能,可是Decorator能夠提供比繼承更多的靈活性。
二、經過使用不一樣的具體裝飾類以及這些裝飾類的排列組合,設計師能夠創造出不少不一樣行爲的組合。
缺點:
一、Decorator模式比繼承更加靈活機動的特性,也同時意味着更加多的複雜性。
二、Decorator模式會致使設計中出現許多小類,若是過分使用,會使程序變得很複雜。
三、Decorator模式是針對抽象組件(Component)類型編程。可是,若是你要針對具體組件編程時,就應該從新思考你的應用架構,以及裝飾者是否合適。固然也能夠改變Component接口,增長新的公開的行爲,實現「半透明」的裝飾者模式。在實際項目中要作出最佳選擇。
補充:
爲了更好的理解裝飾者模式,此處添加一個在網上看到一個感受很是不錯的實例:
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("開始執行具體的對象-蘋果手機"); } } 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("蘋果手機貼膜"); } } public class Accessories : Decorator { public override void Print() { base.Print(); AddAccessories(); } public void AddAccessories() { Console.WriteLine("蘋果手機掛件"); } }
結果以下: