定義:(Decorator Pattern)
動態(tài)地給一個對象添加一些額外的職責(zé)。就增加功能來說胁后,裝飾模式相比生成子類更為靈活店读。
類圖:
啟示:
最近兩年,樓市瘋狂攀芯,房價漲的離譜屯断。這不,為了在深圳有個自己的小家,筆者當(dāng)然也要出去看看房啊殖演,合適就出手買一套啊氧秘。首先在網(wǎng)上就是一通了解啊,深圳的房價基本5萬起步趴久,動輒十萬以上丸相。算了,筆者這點小工資就只能退而求其次彼棍,去惠州看房去灭忠。
第一次看房,難免不懂門道座硕。先跟著銷售轉(zhuǎn)轉(zhuǎn)看吧弛作。
先去看看毛坯房,那完全沒有感覺啊华匾。粗糙地面映琳,水電未通。
算了還是直接去看樣板房吧蜘拉。
樣板房一進(jìn)門就不一樣啊萨西,那裝修,那氣派诸尽,那家具原杂,往沙發(fā)一坐,家的感覺立馬油然而生D!年局!
這一坐不打緊际看,靈感乍現(xiàn)啊,毛坯房和樣板房不就是裝飾模式的現(xiàn)實實例嗎矢否?仲闽!
來來來,上代碼僵朗,咱看看裝飾模式的具體實現(xiàn)赖欣。
代碼:
先看看毛坯房的簡單實現(xiàn):
/// <summary>
/// 抽象房類
/// </summary>
public abstract class AbstractHouse
{
/// <summary>
/// 面積
/// </summary>
public double Area { get; set; }
/// <summary>
/// 規(guī)格
/// </summary>
public string Specification { get; set; }
/// <summary>
/// 價格
/// </summary>
public decimal Price { get; set; }
/// <summary>
/// 定義抽象方法--展示
/// </summary>
public abstract void Show();
}
/// <summary>
/// 未裝修房 -- 毛坯房
/// </summary>
public class WithoutDecoratorHouse : AbstractHouse
{
/// <summary>
/// 毛坯房就做簡要展示
/// </summary>
public override void Show()
{
Console.WriteLine(string.Format("該戶型為{0}㎡,戶型設(shè)計為{1}验庙,目前均價為{2}元/㎡顶吮。", this.Area, this.Specification, this.Price));
}
}
毛坯房真是內(nèi)行看門道,外行看熱鬧啊粪薛,筆者自然是看不懂啊悴了。
走看看樣板房去。
/// <summary>
/// 裝修房
/// </summary>
public abstract class DecoratorHouse : AbstractHouse
{
private readonly AbstractHouse house;
public DecoratorHouse(AbstractHouse house)
{
this.house = house;
}
public override void Show()
{
this.house.Show();
}
}
/// <summary>
/// 裝修房--樣板房
/// </summary>
public class ModelHouse : DecoratorHouse
{
public ModelHouse(AbstractHouse house) : base(house)
{
}
/// <summary>
/// 展示樣板房細(xì)節(jié)
/// </summary>
private void ShowDetail()
{
Console.WriteLine(@"
* 首先,您看到的是我們大概5平方的簡單實用的入戶花園湃交。
* 樣板間的整體按歐式風(fēng)格裝修熟空,精致溫馨。
* 進(jìn)門右看是我們的餐廚一體化設(shè)計搞莺,客廳與餐廳動線相連息罗,擴(kuò)大了整個的空間視野。
* 與客廳無縫連接的是超大的觀景陽臺才沧,東南朝向迈喉,陽光充沛。
* 動靜分離的設(shè)計糜工,將客廳與臥室進(jìn)行有效的分離弊添,保證了私密性及舒適度。
* 主臥的落地窗設(shè)計捌木,提供了足夠的室內(nèi)的采光度油坝。
* 主臥旁邊的是干濕分離的衛(wèi)生間。
* 再旁邊就是兩個緊挨的房間刨裆,可按居家情況設(shè)計為兒童房澈圈、老人房或書房。");
}
public override void Show()
{
base.Show();
ShowDetail();
}
}
經(jīng)過銷售人員這么一講解帆啃,然后往樣板房客廳的沙發(fā)上一坐瞬女,是不是立馬就有家的感覺?努潘!好诽偷,就這個戶型了。
上場景類:
static void Main(string[] args)
{
Console.WriteLine("裝飾模式:");
Console.WriteLine("-------------------------------------------------");
Console.WriteLine("先看毛坯房:");
//未經(jīng)裝修的毛坯房
var withoutDecoratorHouse = new WithoutDecoratorHouse()
{
Area = 80.0,
Specification="三室一廳一衛(wèi)",
Price = 8000
};
withoutDecoratorHouse.Show();
Console.WriteLine("-------------------------------------------------");
Console.WriteLine("再看樣板房:");
//對毛坯房進(jìn)行裝修
var decoratorHouse = new ModelHouse(withoutDecoratorHouse);
decoratorHouse.Show();
Console.WriteLine("-------------------------------------------------");
Console.ReadLine();
}
總結(jié)
裝飾模式是通過Decorator(裝飾角色)構(gòu)造函數(shù)的注入對被裝飾者者的引用疯坤,來間接完成對被裝飾對象功能的動態(tài)添加报慕。
優(yōu)缺點:
優(yōu)點
裝飾類和被裝飾類可以獨立發(fā)展且不相互耦合。
裝飾模式是繼承關(guān)系的一個替代方案压怠。
裝飾模式可以動態(tài)地擴(kuò)展一個實現(xiàn)類的功能眠冈。
缺點
多層的裝飾的情況下,導(dǎo)致層層嵌套菌瘫,導(dǎo)致代碼緊耦合蜗顽。
應(yīng)用場景:
需要擴(kuò)展一個類的功能,或給一個類增加附加功能雨让。
需要動態(tài)地給一個對象增加功能雇盖,這些功能可以再動態(tài)地撤銷。
要為一批的兄弟類進(jìn)行改裝或加裝功能宫患,當(dāng)然是首選裝飾模式刊懈。