裝飾模式(decorator pattern)
一句話
繼承乙個抽象類,加上自己的特點,然後再使自己也變成抽象類,然後讓子類繼承的模式,叫裝飾模式。
意圖
動態地給乙個物件新增一些額外的職責。就增加功能來說,decorator模式相比生成子類更為靈活。
結構圖
生活中的例子
我們還是拿咖啡來舉例子,現在有需要泡一杯咖啡出來。泡咖啡的幾個步驟:
1.磨咖啡豆
2.煮。
先定義乙個介面
public inte***ce makecoffee
//來一杯藍山咖啡
public class
blue_mountain_coffee :
makecoffee
public void cook()
}如果是按一般的方法,在介面內加入「做泡泡(bubbles)」的行為。但是這樣的話,做其他咖啡的時候都必須去實現bubbles
的行為,這樣**就很羅嗦。
所以,我們引入乙個簡單的處理,裝飾模式(decorator pattern)
public abstract class decorator :
makecoffee
所有要做泡泡的咖啡都來繼承這個類。
//來一杯卡布奇諾咖啡
public class
: makecoffee
public void cook()
public void
bubbles
()public void
makecoffee()}
好了,打完收工。
裝飾模式解說
我們分析一下這樣會帶來什麼好處?首先對於擴充套件功能已經實現了真正的動態增加,只在需要某種功能的時候才進行包裝;其次,如果再出現一種新的擴充套件功能,只需要增加乙個對應的包裝子類(注意:這一點任何時候都是避免不了的),而無需再進行很多子類的繼承,不會出現子類的膨脹,同時decorator模式也很好的符合了物件導向設計原則中的「優先使用物件組合而非繼承」和「開放-封閉」原則。
.net中的裝飾模式
1..net中decorator模式乙個典型的運用就是關於stream,它存在著如下的類結構:
可以看到,bufferedstream和cryptostream其實就是兩個包裝類,這裡的decorator模式省略了抽象裝飾角色(decorator),示例**如下:
class
program
);//
擴充套件了緩衝的功能
bufferedstream buff = new
bufferedstream(ms);
//擴充套件了緩衝,加密的功能
cryptostream crypto = new
cryptostream(buff);}}
通過反編譯,可以看到bufferedstream類的**(只列出部分),它是繼承於stream類:
示意性**如下:
public
abstract
class
public
class
public
class
效果及實現要點
1.component類在decorator模式中充當抽象介面的角色,不應該去實現具體的行為。而且decorator類對於component類應該透明,換言之component類無需知道decorator類,decorator類是從外部來擴充套件component類的功能。
2.decorator類在介面上表現為is-a component的繼承關係,即decorator類繼承了component類所具有的介面。但在實現上又表現為has-a component的組合關係,即decorator類又使用了另外乙個component類。我們可以使用乙個或者多個decorator物件來「裝飾」乙個component物件,且裝飾後的物件仍然是乙個component物件。
3.decortor模式並非解決「多子類衍生的多繼承」問題,decorator模式的應用要點在於解決「主體類在多個方向上的擴充套件功能」——是為「裝飾」的含義。
4.對於decorator模式在實際中的運用可以很靈活。如果只有乙個concretecomponent類而沒有抽象的component類,那麼decorator類可以是concretecomponent的乙個子類。
如果只有乙個concretedecorator類,那麼就沒有必要建立乙個單獨的decorator類,而可以把decorator和concretedecorator的責任合併成乙個類。
5.decorator模式的優點是提供了比繼承更加靈活的擴充套件,通過使用不同的具體裝飾類以及這些裝飾類的排列組合,可以創造出很多不同行為的組合。
6.由於使用裝飾模式,可以比使用繼承關係需要較少數目的類。使用較少的類,當然使設計比較易於進行。但是,在另一方面,使用裝飾模式會產生比使用繼承關係更多的物件。更多的物件會使得查錯變得困難,特別是這些物件看上去都很相像。
適用性
在以下情況下應當使用裝飾模式:
1.需要擴充套件乙個類的功能,或給乙個類增加附加責任。
2.需要動態地給乙個物件增加功能,這些功能可以再動態地撤銷。
3.需要增加由一些基本功能的排列組合而產生的非常大量的功能,從而使繼承關係變得不現實。
總結
decorator模式採用物件組合而非繼承的手法,實現了在執行時動態的擴充套件物件功能的能力,而且可以根據需要擴充套件多個功能,避免了單獨使用繼承帶來的「靈活性差」和「多子類衍生問題」。同時它很好地符合物件導向設計原則中「優先使用物件組合而非繼承」和「開放-封閉」原則。
設計模式 裝飾模式
裝飾模式,動態地給乙個物件新增一些額外的職責,就增加功能來說,裝飾模式比生成子類更為靈活。m 超級瑪麗 普通繼承模式實現 a 發鏢 能組合出七種功能 m1 a m4 a b b 變身 m2 b m5 a c c 無敵 m3 c m6 b c m7 a b m m1 a b 組合方法 new m2 m...
設計模式 裝飾模式
剛看了看設計模式,真是費了好多的腦細胞。想著想著就到了食堂。o o哈!正是長身體的時候 大神勿噴 一定要多吃點。於是我打了乙份公尺飯,然後又端著盛公尺飯的盤子買了乙份菜 看著還不是很夠,就又端著這個盤子買了一條最愛吃的魚。裝飾模式!五一要來了。回家轉轉,沒有小外甥的玩具怎麼行。於是我去超市,推著購物...
設計模式 裝飾模式
複習設計模式 裝飾模式 裝飾模式 在不修改已經存在的類的情況下,動態的新增新的功能,實現即插即用,開放關閉原則 public inte ce man public class batman implements man override public void killmonster public ...