定義:(Decorator Pattern)
動態地給一個對象添加一些額外的職責。就增加功能來說,裝飾模式相比生成子類更為靈活。
類圖:
裝飾模式通用類圖
啟示:
最近兩年,樓市瘋狂,房價漲的離譜。這不,為了在深圳有個自己的小家,筆者當然也要出去看看房啊,合適就出手買一套啊。首先在網上就是一通了解啊,深圳的房價基本5萬起步,動輒十萬以上。算了,筆者這點小工資就只能退而求其次,去惠州看房去。
第一次看房,難免不懂門道。先跟著銷售轉轉看吧。
先去看看毛坯房,那完全沒有感覺啊。粗糙地面,水電未通。
毛坯房
算了還是直接去看樣板房吧。
樣板房一進門就不一樣啊,那裝修,那氣派,那家具,往沙發一坐,家的感覺立馬油然而生!!!
樣板房
這一坐不打緊,靈感乍現啊,毛坯房和樣板房不就是裝飾模式的現實實例嗎?!
來來來,上代碼,咱看看裝飾模式的具體實現。
代碼:
先看看毛坯房的簡單實現:
/// <summary>
/// 抽象房類
/// </summary>
public abstract class AbstractHouse
{
/// <summary>
/// 面積
/// </summary>
public double Area { get; set; }
/// <summary>
/// 規格
/// </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}㎡,戶型設計為{1},目前均價為{2}元/㎡。", this.Area, this.Specification, this.Price));
}
}
毛坯房真是內行看門道,外行看熱鬧啊,筆者自然是看不懂啊。
走看看樣板房去。
/// <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>
/// 展示樣板房細節
/// </summary>
private void ShowDetail()
{
Console.WriteLine(@"
* 首先,您看到的是我們大概5平方的簡單實用的入戶花園。
* 樣板間的整體按歐式風格裝修,精致溫馨。
* 進門右看是我們的餐廚一體化設計,客廳與餐廳動線相連,擴大了整個的空間視野。
* 與客廳無縫連接的是超大的觀景陽臺,東南朝向,陽光充沛。
* 動靜分離的設計,將客廳與臥室進行有效的分離,保證了私密性及舒適度。
* 主臥的落地窗設計,提供了足夠的室內的采光度。
* 主臥旁邊的是干濕分離的衛生間。
* 再旁邊就是兩個緊挨的房間,可按居家情況設計為兒童房、老人房或書房。");
}
public override void Show()
{
base.Show();
ShowDetail();
}
}
經過銷售人員這么一講解,然后往樣板房客廳的沙發上一坐,是不是立馬就有家的感覺?!好,就這個戶型了。
上場景類:
static void Main(string[] args)
{
Console.WriteLine("裝飾模式:");
Console.WriteLine("-------------------------------------------------");
Console.WriteLine("先看毛坯房:");
//未經裝修的毛坯房
var withoutDecoratorHouse = new WithoutDecoratorHouse()
{
Area = 80.0,
Specification="三室一廳一衛",
Price = 8000
};
withoutDecoratorHouse.Show();
Console.WriteLine("-------------------------------------------------");
Console.WriteLine("再看樣板房:");
//對毛坯房進行裝修
var decoratorHouse = new ModelHouse(withoutDecoratorHouse);
decoratorHouse.Show();
Console.WriteLine("-------------------------------------------------");
Console.ReadLine();
}
運行結果
總結
裝飾模式是通過Decorator(裝飾角色)構造函數的注入對被裝飾者者的引用,來間接完成對被裝飾對象功能的動態添加。
優缺點:
優點
裝飾類和被裝飾類可以獨立發展且不相互耦合。
裝飾模式是繼承關系的一個替代方案。
裝飾模式可以動態地擴展一個實現類的功能。
缺點
多層的裝飾的情況下,導致層層嵌套,導致代碼緊耦合。
應用場景:
需要擴展一個類的功能,或給一個類增加附加功能。
需要動態地給一個對象增加功能,這些功能可以再動態地撤銷。
要為一批的兄弟類進行改裝或加裝功能,當然是首選裝飾模式。