概念:動態給一個對象添加額外的職責,就增加功能來說,裝飾模式比產生子類更為靈活。
結構圖:
解析:
Component類:
定義一個對象介面,可以給這些對象動態添加職責(方法)。
ConcreteComponent類:
定義了一個具體的對象,也可以給這個對象添加職責。
Decorator類:
裝飾抽象類別,繼承Component,從外類來擴充Component類的功能,但對於Component來說,是無需知道Decorator的存在的。
ConcreteDecorator類:
具體的裝飾對象,起到給Component添加職責的功能。
注意:
如果只有一個ConcreteComponent類而沒有抽象的Component類,那麼Decorator類可是ConcreteComponent的一個子類,同樣道理,如果只有一個ConcreteDecorator類,那麼就沒有必要建立一個單獨的Decorator類,而可以把Decorator和ConcreteDecorator的責任合并成一個類。
先看結構一個結構圖:
此時,沒有Component類,將“人“這個類看成是Component類和ConcreteComponent類的綜合體,那麼”服飾類“(Decorator類)可以看成是其一個子類,後面的球鞋類、西裝類、領帶類、皮鞋類都是具體的裝飾對象。
執行個體:
結構圖:
代碼實現:
Photot life = new LifePhoto(); Photot art= new ArtPhoto (); //life.Display (); //art.Display (); PhotoFrame glass=new GlassPhotoFrame (life ); glass .Display (); PhotoFrame ruby = new RubyPhotoFrame(art ); ruby.Display (); } } //對象介面 abstract class Photot { public abstract void Display(); } //具體對象 class LifePhoto : Photot //具體對象一 { public override void Display() { Console.WriteLine("生活照"); } } class ArtPhoto : Photot //具體對象二 { public override void Display() { Console .WriteLine ("藝術照"); } } //裝飾抽象類別 abstract class PhotoFrame : Photot { private Photot photo; public PhotoFrame (Photot photo) { this.photo=photo ; } public override void Display() { photo.Display(); } } //具體裝飾對象 class GlassPhotoFrame : PhotoFrame //裝飾對象一 { public GlassPhotoFrame(Photot photo) : base(photo) { } public override void Display() { Console.WriteLine("加了玻璃相框"); base.Display(); } } class RubyPhotoFrame : PhotoFrame //裝飾對象二 { public RubyPhotoFrame(Photot photo) : base(photo) { } public override void Display() { Console.WriteLine("紅寶石色相框"); base.Display(); } }
運行結果:
優點:
第一:使書寫的代碼具有柔韌性,能夠以一系列的功能來增加代替對象的行為,它不會汙染原有的代碼,反而會讓代碼容易編寫,容易對外擴充。
第二:它將每個功能放在一個單獨的類中,讓這個類去封裝要裝飾的對象,這樣就將裝飾功能類與原有的類分開,簡化了原有類,類的核心職責和裝飾功能也區分開了,而且相關類中重複的裝飾邏輯也沒有了。
缺點:
第一:如果原有的對象的介面發生變化了,那麼他所有的裝飾類也得修改,進而匹配介面。
第二:如果裝飾鏈過大,系統就會花費較長的時間去用於初始化對象,影響資訊的傳遞。
適用範圍:
第一:想在不影響其他類的情況下,動態給對象添加新的職責方法;
第二:給對象增加職責可能會在未來發生改變;
第三:用子類來擴充功能不方便的情況下。