裝飾者模式定義:不透過衍生類別增改類別屬性動作,而是透過模式設計動態的達到這種效果,而且比繼承更方便靈活減少程式的複雜性。
舉例
汪峰打造冠軍團隊。
首先團隊類為空,經過汪峰不斷的努力,為團隊爭取學員,也為團隊隊員打造合適的平台,讓其發揮。
團隊不斷的變強,變完整,是由裝飾者,根據不同的需求,給基類進行增改,一致最後贏得你的讚同,滿足你的需求。
實現組裝器模式的類別圖:
戰隊組成代碼
//汪峰战队 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("婉约型,走秀"); } }
客戶端代碼:
public 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動態增加功能的。
MemoryStream 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);
總結
到這裡,裝飾者模式的介紹就結束了,裝飾者模式採用對象組合而非繼承的方式實現了再運行時動態地擴展對像功能的能力,而且可以根據需要擴展多個功能,避免了單獨使用繼承帶來的”靈活性差“和”多子類衍生問題“。同時它很好地符合物件導向設計原則中 」優先使用物件組合而非繼承「和」開放-封閉「原則。
更多解析C#設計模式編程中的裝飾者模式相關文章請關注PHP中文網!