C#實現(xiàn)裝飾器模式
場景:假設(shè)每次我們?nèi)コ匈徫?,我們都會推一個購物車,有水果、蔬菜、肉類三種商品,提供給我們選擇,那么這時候,如果使用裝飾器模式,應(yīng)該如何實現(xiàn)?
1.什么是裝飾器模式
首先我們知道,如果想要給一個類或者對象添加一些行為,可以通過繼承這樣的機制,通過子類繼承父類的方式,使得子類在擁有自己的行為的時候,同時也繼承了父類的一些方法。但是繼承的方式,使得子類和父類之間的耦合增大了,并且這種方法是靜態(tài)的,用戶不能控制增加行為的方式和時機。
還有一種方式是使用關(guān)聯(lián)機制,將一個類對象嵌入到另一個對象中,由另一個對象來決定是否調(diào)用嵌入對象的行為,以便擴展自己的行為,這種嵌入的對象就成為裝飾器
那么裝飾器模式的動機就是:裝飾模式可以在不需要創(chuàng)造更多子類的情況下,將對象的功能加以擴展。這就是裝飾模式的模式動機。
裝飾器模式的設(shè)計圖如下:
- Component: 抽象構(gòu)件
- ConcreteComponent: 具體構(gòu)件
- Decorator: 抽象裝飾類
- ConcreteDecorator: 具體裝飾類
2.實現(xiàn)場景
根據(jù)這個設(shè)計圖,我們可以設(shè)計一下上面場景的實現(xiàn)
①.原始類-就是那個購物車(shoppingCart)
②.繼承類A-這里沒有繼承,所以這部分不需要,如果以后需要對購物車的種類進行再細(xì)致的劃分,可以使用
③.裝飾器基類(BaseDecorator)
④.裝入水果、蔬菜、肉類就對應(yīng)下面的三個裝飾器A、B、C
實現(xiàn)代碼:
ShoppingCart.cs
public class ShoppingCart { public virtual void Show() { } }
BaseDecorator.cs
public class BaseDecorator:ShoppingCart { protected ShoppingCart _shoppingCart; public BaseDecorator(ShoppingCart shoppingCart) { _shoppingCart = shoppingCart; } public override void Show() { if (_shoppingCart != null) { base.Show(); } } }
FruitsDecorator.cs
public class FruitsDecorator:BaseDecorator { public FruitsDecorator(ShoppingCart shoppingCart) : base(shoppingCart) { } public void addFruits() { Console.WriteLine("加入了水果。"); } public override void Show() { base.Show(); addFruits(); } }
MeatsDecorator.cs
public class MeatsDecorator : BaseDecorator { public MeatsDecorator(ShoppingCart shoppingCart) : base(shoppingCart) { } public void addMeat() { Console.WriteLine("加入了肉。"); } public override void Show() { base.Show(); addMeat(); } }
VegetablesDecorator.cs
public class VegetablesDecorator : BaseDecorator { public VegetablesDecorator(ShoppingCart shoppingCart) : base(shoppingCart) { } public void addVegetable() { Console.WriteLine("加入蔬菜。"); } public override void Show() { base.Show(); addVegetable(); } }
Program.cs
ShoppingCart sc = new ShoppingCart(); BaseDecorator bd = new BaseDecorator(sc); //添加水果 FruitsDecorator fd = new FruitsDecorator(bd); fd.Show(); //添加肉 MeatsDecorator md = new MeatsDecorator(fd); md.Show(); //添加蔬菜 VegetablesDecorator vd = new VegetablesDecorator(md); vd.Show();
測試執(zhí)行:
3.其他應(yīng)用場合
在C#當(dāng)中,應(yīng)用裝飾器的場景是蠻多的,比較典型的是System.IO.Stream
例如使用壓縮流的時候
//壓縮數(shù)據(jù) static Byte[] Compress(Byte[] data) { //壓縮入這個內(nèi)存流 using (MemoryStream target = new MemoryStream()) { using (GZipStream gs = new GZipStream(target,CompressionMode.Compress,true)) { //把數(shù)據(jù)寫入到壓縮流當(dāng)中 //具體實現(xiàn)略 } return target.ToArray(); } }
4.總結(jié)
優(yōu)點:
裝飾這模式和繼承的目的都是擴展對象的功能,但裝飾者模式比繼承更靈活
通過使用不同的具體裝飾類以及這些類的排列組合,設(shè)計師可以創(chuàng)造出很多不同行為的組合
裝飾者模式有很好地可擴展性
缺點:
裝飾者模式會導(dǎo)致設(shè)計中出現(xiàn)許多小對象,如果過度使用,會讓程序變的更復(fù)雜。并且更多的對象會是的差錯變得困難,特別是這些對象看上去都很像。
使用場景:
需要擴展一個類的功能或給一個類增加附加責(zé)任。
需要動態(tài)地給一個對象增加功能,這些功能可以再動態(tài)地撤銷。
需要增加由一些基本功能的排列組合而產(chǎn)生的非常大量的功能
到此這篇關(guān)于C#實現(xiàn)裝飾器模式的文章就介紹到這了。希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C#中隱藏TabControl選項卡標(biāo)簽的解決方案
這篇文章主要介紹了C#中隱藏TabControl選項卡標(biāo)簽的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-04-04C# TextBox控件實現(xiàn)只能輸入數(shù)字的方法
這篇文章主要介紹了C# TextBox控件實現(xiàn)只能輸入數(shù)字的方法,本文使用TextBox的keypress事件實現(xiàn)這個需求,需要的朋友可以參考下2015-06-06C#調(diào)用WinRar執(zhí)行rar、zip壓縮的方法
這篇文章主要介紹了C#調(diào)用WinRar執(zhí)行rar、zip壓縮的方法,涉及C#針對winrar的判斷與調(diào)用技巧,需要的朋友可以參考下2015-05-05C#實現(xiàn)Word和ODT文檔相互轉(zhuǎn)換詳解
ODT文檔格式一種開放文檔格式(OpenDocument Text)。本文以C#及VB.NET代碼展示ODT和Word文檔之間相互轉(zhuǎn)換的方法,感興趣的可以學(xué)習(xí)一下2022-05-05C#實現(xiàn)appSettings節(jié)點讀取與修改的方法
這篇文章主要介紹了C#實現(xiàn)appSettings節(jié)點讀取與修改的方法,是非常實用的技巧,需要的朋友可以參考下2014-10-10