概述 裝飾器模式 允許向一個現有的對象添加新的功能,同時又不改變其結構。這種類型的設計模式屬於結構型模式,它是作為現有的類的一個包裝。這種模式創建了一個裝飾類,用來包裝原有的類,併在保持類方法簽名完整性的前提下,提供了額外的功能。 簡單理解就是動態的給一個對象添加一些額外的職責,就增加功能來說,裝飾 ...
概述
裝飾器模式 允許向一個現有的對象添加新的功能,同時又不改變其結構。這種類型的設計模式屬於結構型模式,它是作為現有的類的一個包裝。這種模式創建了一個裝飾類,用來包裝原有的類,併在保持類方法簽名完整性的前提下,提供了額外的功能。
簡單理解就是動態的給一個對象添加一些額外的職責,就增加功能來說,裝飾模式比生成子類更為靈活。
我們還是堅持以往的風格,提一個需求,然後用裝飾器模式實現一下。
類圖
該類圖來源網上
裝飾器模式主要組成部分
Component:定義一個對象介面,可以給這些對象動態地添加職責;
ConcreteComponent:定義一個對象,繼承Component,可以給這個對象添加一些職責;
Decorator:維持一個指向Component的指針,並定義一個與Component介面一致的介面;
ConcreteDecorator:負責向ConcreteComponent添加功能;
在裝飾模式中,Decorator定義了一個裝飾介面類。因為Decorator與ConcreteComponent繼承同一個介面,所以繼承Decorator的類ConcreteDecorator可以使用ConcreteComponent的方法,再在ConcreteDecorator裡面加入一些新的方法,也就是裝飾,就成為了一個包裝好的裝飾類。
需求
想要一杯奶茶,添加兩份布丁,一份珍珠,該如何實現?將來還可能添加更多的配料;
使用裝飾器模式的代碼
/// <summary> /// 相當於Component /// </summary> public abstract class YinLiao { public abstract double Cast(); } /*==================茶的種類=====================*/ /// <summary> /// 相當於ConcreteComponent /// </summary> public class MilkTea : YinLiao { public override double Cast() { Console.WriteLine("奶茶10塊錢一杯"); return 10; } } /// <summary> /// 相當於ConcreteComponent /// </summary> public class FruitTea : YinLiao { public override double Cast() { Console.WriteLine("水果茶15塊錢一杯"); return 15; } } /// <summary> /// 相當於ConcreteComponent /// </summary> public class SodaTea : YinLiao { public override double Cast() { Console.WriteLine("蘇打水4塊錢一杯!"); return 4; } } /// <summary> /// 裝飾器模式第一個核心 /// </summary> public abstract class Decorator : YinLiao { /// <summary> /// 添加一個父類的引用 /// </summary> private YinLiao yinLiao; /// <summary> /// 通過set方法賦值 /// </summary> /// <param name="yinLiao"></param> public void SetComponent(YinLiao yinLiao) { this.yinLiao = yinLiao; } public override double Cast() { return this.yinLiao.Cast(); } } /*====================配料類======================================*/ /// <summary> /// 相當於ConcreteDecorator /// </summary> public class BuDing : Decorator { private static double money = 5; public override double Cast() { Console.WriteLine("布丁5塊"); //第二個核心 return base.Cast() + money; } } /// <summary> /// 相當於ConcreteDecorator /// </summary> public class Zhenzhu : Decorator { private static double money = 7; public override double Cast() { Console.WriteLine("珍珠7塊"); //第二個核心 return base.Cast() + money; } } /// <summary> /// 相當於ConcreteDecorator /// </summary> public class XianCao : Decorator { private static double money = 6; public override double Cast() { Console.WriteLine("仙草6塊"); //第二個核心 return base.Cast() + money; } }
//C#控制台調用 Console.WriteLine("裝飾器設計模式!"); /* 茶裡面添加兩份布丁、一份珍珠*/ MilkTea milkTea = new MilkTea(); BuDing buDing1 = new BuDing(); BuDing buDing2 =new BuDing(); Zhenzhu zhenzhu = new Zhenzhu(); buDing1.SetComponent(milkTea); buDing2.SetComponent(buDing1); zhenzhu.SetComponent(buDing2); Console.WriteLine(zhenzhu.Cast());
zhenzhu.Cast() 執行的順序為先 zhenzhu.Cast()方法裡面的邏輯、 zhenzhu.Cast()方法的bast.cast()又會去執行buDing2.cast()、buDing2.cast()又會去執行buDing1.cast(),直至執行完milkTea.cast(),最後所有的base.cast()邏輯執行完後,返回接著執行zhenzhu.Cast()邏輯結果為27;
關於這段控制台調用的代碼邏輯比較繞一點,像洋蔥一樣,一層一層從外面往裡面執行。感興趣的建個控制台調試一把試試。整體類似如下圖:
總結
個人感覺設計模式越往後學越簡單,比如像裝飾器設計模式說白了就是拓展功能,像上一篇文章我們學習的適配器設計模式就是轉換輸出。
作者:realyrare
出處:https://www.cnblogs.com/mhg215/
聲援博主:如果您覺得文章對您有幫助,請點擊文章末尾的【關註我】吧!
別忘記點擊文章右下角的【推薦】支持一波。~~~///(^v^)\\\~~~ .
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。
如果您有其他問題,也歡迎關註我下方的公眾號,可以聯繫我一起交流切磋!