裝飾器模式簡介 裝飾器模式是動態的向一個對象添加新的功能,並且保持其類方法簽名的完整性,換言之,其方法及繼承結構將不會被改變。這種模式一種結構型模式,是對現有類的包裝。這種模式,比生成子類更加靈活,更重要的是,裝飾者模式裝飾的是特定的行為或者或是職責,也沒有必要通過子類實現。 在日常生活中,裝飾器模 ...
裝飾器模式簡介
裝飾器模式是動態的向一個對象添加新的功能,並且保持其類方法簽名的完整性,換言之,其方法及繼承結構將不會被改變。這種模式一種結構型模式,是對現有類的包裝。這種模式,比生成子類更加靈活,更重要的是,裝飾者模式裝飾的是特定的行為或者或是職責,也沒有必要通過子類實現。
在日常生活中,裝飾器模式的場景更多是的打扮了,一個妹子,嫌棄自己的臉長得不夠漂亮,想換張臉很困難,但是化化妝還是很容易的(當然了,化妝也分男女的,此處指的是女士化妝,大老爺們有啥好化的,還不如收拾山河,收復釣魚島),加點粉底啊,塗點腮紅啊,塗眼影,畫眼線,再加點口紅,哇塞,一個大美女就這樣誕生了,這就是打扮的力量,這就是裝飾的力量,這也是愛美的力量。寫到這裡我突然想到一句話就是,清水出芙蓉,天然去雕飾,當自然不能使之完美時,藝術使之完美。
裝飾器模式就是,在一個已經先天不足或者未來有可能需要擴展的場景中,修改代碼將是一件工作量十分巨大的事情,也是危險繫數比較高的事情,我們需要以一個比較經濟、安全的方式來解決這個問題,可以認為是從周邊方式、從外圍方式來解決問題。
這個例子也告訴我們,生活處處是學問,紙上得來終覺淺,覺知此時要躬行,當你看到這篇文章的時候,不必太過糾結於其定義或者UML,你可以更多的去類比你的生活,這樣你會更快更深刻的獲取知識。
裝飾器模式UML類圖
小提醒
裝飾器類繼承並依賴於更抽象一級的IWoman介面,在地位上與Face、Clothes一致
裝飾器類對IWoman介面的方法進行了包裝,隱隱約約有模板方法模式的影子
範例
以下範例,會使用前面所說的女人喜歡打扮使用打扮方式解決自然問題或者說更進一層樓的問題,女人的打扮有方方面面的,不過最常見也就是化妝和穿衣,所以此處使用這兩個裝扮方式予以Coding。
抽象介面:
1: public interface IWoman
2: {
3: void Attire();
4: }
臉部打扮
1: public class Face : IWoman
2: {
3: public void Attire()
4: {
5: Console.Write("那些年還不會打扮,擦點自己也不知道是什麼的粉");
6: }
7: }
穿衣打扮
1: public class Clothes : IWoman
2: {
3: public void Attire()
4: {
5: Console.Write("那些年還不會打扮,穿點屌絲裝");
6: }
7: }
裝飾器抽象類
1: public abstract class RougeDecorator : IWoman
2: {
3: protected IWoman woman;
4:
5: public RougeDecorator(IWoman woman)
6: {
7: this.woman = woman;
8: }
9:
10: public virtual void Attire()
11: {
12: this.woman.Attire();
13: }
14: }
臉部增加裝飾
1: public class FaceDecorator : RougeDecorator
2: {
3: public FaceDecorator(IWoman woman) : base(woman)
4: {
5: }
6:
7: public override void Attire()
8: {
9: this.woman.Attire();
10: Console.WriteLine("這些年學會了打扮,還要繼續化妝,塗眼影,畫眼線");
11: }
12: }
穿衣增加裝飾
1: public class ClothesDecorator : RougeDecorator
2: {
3: public ClothesDecorator(IWoman woman) : base(woman)
4: {
5: }
6:
7: public override void Attire()
8: {
9: this.woman.Attire();
10: Console.WriteLine("這些年學會了打扮,打底褲,包臀裙,上衣也要換一下,名牌穿起,還要再戴個帽子,回頭率必須杠杠的");
11: }
12: }
調用
1: class Program
2: {
3: static void Main(string[] args)
4: {
5: IWoman womanFace = new Face();
6: IWoman womanDress = new Clothes();
7:
8: IWoman womanFaceDecorator = new FaceDecorator(womanFace);
9: IWoman womanClothesDecorator = new ClothesDecorator(womanDress);
10:
11: womanFaceDecorator.Attire();
12: womanClothesDecorator.Attire();
13:
14: Console.WriteLine("----------------------------------------------------");
15: Console.WriteLine("完美女人出現了");
16: Console.WriteLine("既然完美女人已經出現了,那就抓緊娶回家,然後把裝飾器給關掉");
17: Console.WriteLine("卧槽,貌似有點難關呀,該死的裝飾器");
18: Console.WriteLine("難不倒我,把你化妝品換成路攤貨,越塗越難看,哈哈,難不倒我程式員");
19:
20: Console.ReadLine();
21: }
22: }
調用結果如下圖所示
裝飾器模式優缺點
優點:
- 很好的利用了開閉原則,裝飾類和被裝飾類可以獨立發展,不會相互耦合。
- 裝飾模式是繼承的一個替代模式,可以動態擴展一個實現類的功能
缺點:
- 裝飾模式會使得業務及代碼變得複雜
裝飾器模式使用場景思考
裝飾器模式,從某種角度上說,可能更適合用於對已經成型的業務進行修改的場景,不管是用於動態擴展,還是動態移除,裝飾器都能很方便的勝任對對象的修改操作。另外就是,繼承也可以解決類似問題,但是裝飾器可以更好的擴展,因為,我們一般解決的是特定對象的特定行為,而不會對整個對象進行修改,這樣子跟大型重構沒有什麼區別。所以,特定場景的修改,裝飾器來的更快,更簡單,更有效率,沒有必要興師動眾。
以上為本篇文章的主要內容,希望大家多提提意見,如果喜歡記得點個贊哦