一、描述
需要擴展一個類的功能,或給一個類增加附加責任,這些功能可以再動態地撤銷。裝飾器模式相比生成子類更爲靈活,裝飾模式是繼承的一個替代模式。
二、優劣勢
優點:裝飾類和被裝飾類可以獨立發展,不會相互耦合。
缺點:多層裝飾比較複雜,順序特別重要。
三、需求
QQ形象的展示,主要有個人資料,衣服、褲子、鞋子。
四、不使用設計模式
都不考慮設計了,直接擼代碼。
2個類,
QQBase.cs -qq基類
NormalQQ.cs --qq實現類
//QQ基類
public abstract class QQBase
{
public abstract void Show();
}
//QQ對象
public class NormalQQ : QQBase
{
public string name;
public int age;
public NormalQQ(string s,int a)
{
name = s;
age = a;
}
public override void Show()
{
Debug.Log("姓名:"+name+" "+"年齡:"+age);
YiFu();
KuZi();
XieZi();
}
public void YiFu()
{
Debug.Log("穿上衣服");
}
public void KuZi()
{
Debug.Log("穿上褲子");
}
public void XieZi()
{
Debug.Log("穿上鞋子");
}
}
//客戶端調用
public static void main(string[] args)
{
QQBase qQ = new NormalQQ("淺傷",18);
qQ.Show();
}
運行結果
小結:目前的做法是穿衣服、褲子、鞋子的行爲寫在qq實現類裏面,假如我們只需要穿褲子那麼Show方法裏面的調用是不是得修改了,或者說我想改變下順序,想先穿褲子然後再鞋子最後在衣服,是不是也得修改Show裏面的調用。
五、使用設計模式
通過添加裝飾類,把穿物品的行爲放在裏面,並且裝飾類必須也得繼承QQBase基類,爲了統一Show()接口給客戶端調用。
6個類,
QQBase.cs -qq基類
NormalQQ.cs --qq實現類
DecoratorBase.cs --裝飾基類
YiFuDecorator.cs --裝飾衣服類
KuZiDecorator.cs --裝飾褲子類
XieZiDecorator.cs --裝飾鞋子類
//QQ基類
public abstract class QQBase
{
public abstract void Show();
}
//QQ對象
public class NormalQQ : QQBase
{
public string name;
public int age;
public NormalQQ(string s,int a)
{
name = s;
age = a;
}
public override void Show()
{
Debug.Log("姓名:"+name+" "+"年齡:"+age);
}
}
//裝飾類基類,繼承QQBase爲了統一Show接口給客戶端用
public class DecoratorBase : QQBase
{
protected QQBase qq;//持有原來的
//在構造函數裏賦值原對象
public DecoratorBase(QQBase q)
{
qq = q;
}
public override void Show()
{
if (qq!=null)
{
qq.Show();//調用下原對象的Show方法,這裏對應的是原來輸出name和age的作用
}
}
}
//衣服裝飾類
public class YiFuDecorator : DecoratorBase
{
public YiFuDecorator(QQBase q):base(q)
{
}
public override void Show()
{
base.Show();//調用下原對象的Show方法
Debug.Log("穿上了衣服");//這裏就是我們額外可以添加的功能,這邊是穿衣服
}
}
//褲子裝飾類
public class KuZiDecorator : DecoratorBase
{
public KuZiDecorator(QQBase q) : base(q)
{
}
public override void Show()
{
base.Show();//調用下原對象的Show方法
Debug.Log("穿上了褲子");//這裏就是我們額外可以添加的功能,這邊是穿褲子
}
}
//褲子裝飾類
public class XieZiDecorator : DecoratorBase
{
public XieZiDecorator(QQBase q) : base(q)
{
}
public override void Show()
{
base.Show();//調用下原對象的Show方法
Debug.Log("穿上了鞋子");//這裏就是我們額外可以添加的功能,這邊是穿鞋子
}
}
//客戶端調用
public static void main(string[] args)
{
QQBase qQ = new NormalQQ("淺傷",18);
YiFuDecorator yiFuDecorator = new YiFuDecorator(qQ);
KuZiDecorator kuZiDecorator = new KuZiDecorator(yiFuDecorator);
XieZiDecorator xieZiDecorator = new XieZiDecorator(kuZiDecorator);
xieZiDecorator.Show();
}
運行結果
小結:我們通過引入裝飾模式,把原來的穿衣服褲子鞋子行爲單獨從NormalQQ類分離了出來,使得原來的NormalQQ乾淨了不少,比較裝扮衣服這些只是展示的界面才需要用到,所以沒必要放NormalQQ裏面,我們把每個物品都封裝了一個單獨的類,並且持有一個上一個對象,所以調用順序就可以根據自己的需求來賦值了,只需要調用最後使用的裝飾類,就會在裏面一層一層的往上調用Show()方法,假如我們要調整穿的順序,在客戶端那邊調整一下就可以了。
六、設計圖
通過學習,我們瞭解到了裝飾模式的應用,我們把剛剛的實現方式畫出來。
七、進階講解
裝飾模式其實就是適合一些表現上的實現,並且這個表現不是主要核心的功能,我們纔可以單獨分離出來,比如說手機,它的核心的打電話上網,我們在構造手機類的時候不會把鋼化膜、貼子什麼的給它也寫進去,而是在需要展示它的這些裝飾作用的時候才使用裝飾類來給它做一個實現 。
八、總結
覺得有用就留下評論吧^-^