裝飾者設計模式
- 什麼是裝飾者設計模式
- 實戰
什麼是裝飾者設計模式
裝飾者設計模式(Decorator Pattern)将某個方法進行增強,可以在被裝飾的方法執行前後加上想要的邏輯處理進行增強,又可以不改變現有的結構。這種模式建立了一個裝飾類,用來包裝原有的類,并在保持類方法簽名完整性的前提下,提供額外的功能。
使用場景: 1、擴充一個類的功能。 2、動态增加功能,動态撤銷。
注意事項:可代替繼承
實戰
我們利用女孩化妝來示範裝飾者設計模式,首先我們定義一個接口,擁有展示的行為:
public interface Showable {
void show();
}
當然女友會這門功夫了,是以實作了此行為并施展其“美麗的臉龐”了,但此時隻是原生态的素顔。
public class Girl implements Showable {
@Override
public void show() {
System.out.print("女孩的素顔");
}
}
沒什麼複雜的,直接調用的話會是素面朝天直面慘淡的人生,這樣當然達不到美顔效果了,何以一顧傾城。那麼接下來要進行化妝了,這裡必須依靠一種神秘而又昂貴的東西,化妝品登場了,它同樣實作了Showable接口。
public class Decorator implements Showable {
/**
* 擁有某個善于展示的對象
*/
private Showable showable;
public Decorator(Showable showable){
this.showable = showable;
}
@Override
public void show() {
System.out.print("化妝(");
showable.show();
System.out.println(")");
}
}
我們可以發現,在構造化妝品類的時候可以把女孩給注入進來,目的在于調用女孩的show方法,但對于其原本的具體行為裝飾器一無所知,并且沒有加入任何邏輯限制,它所做的無非是“畫龍點睛”,“錦上添花”。接下來我們來運作一下看結果:
public class TestShowable {
public static void main(String[] args) {
//将需要被加強的對象傳遞給裝飾類
new Decorator(new Girl()).show();
//結果:打扮(女孩的素顔)
}
}
我們可以看到,隻需要建立裝飾器的時候把女孩給包裝進去就得到了粉飾過的美顔,是不是非常簡單?然而此時有女朋友會嫌棄了,“隻是打粉底這麼簡單嗎?眼霜呢?口紅呢……”。
好吧,為了滿足女友的要求,我們得再多一些設計。想想看這些化妝品,不管是什麼都有共同的特性,也就是說他們統統都可以裝飾原生态的素顔展示方法show,那我們何不把這些特性抽象出來呢?開始行動,修改我們的裝飾類
public abstract class Decorator implements Showable {
/**
* 擁有某個善于展示的對象
*/
protected Showable showable;
public Decorator(Showable showable){
this.showable = showable;
}
public void show() {
//直接調用,不加任何裝飾
showable.show();
}
}
我們把化妝品類給改成抽象類,重寫show方法,但不做任何粉飾了,這裡我們留給子類具體的某個化妝品去做裝飾吧。化妝首先第一步一定要打底了,這裡我們首先加入一個口紅類:
public class Lipstick extends Decorator{
public Lipstick(Showable showable) {
//調用父類構造指派給成員屬性
super(showable);
}
@Override
public void show() {
System.out.print("塗口紅(");
showable.show();
System.out.print(")");
}
}
塗完口紅,最後再噴點香水吧。同樣的,我們再定義一個香水類:
public class Perfume extends Decorator {
public Perfume(Showable showable) {
super(showable);
}
@Override
public void show() {
System.out.println("噴香水(");
showable.show();
System.out.println(")");
}
}
最後,我們把女友、口紅、香水層層包裹起來并運作,結果如願以償。
public class TestShowable {
public static void main(String[] args) {
//将需要被加強的對象傳遞給裝飾類,層層包裹起來,每一層都多了一些功能
new Perfume(new Lipstick(new Girl())).show();
//結果: 噴香水(塗口紅(女孩的素顔))
}
}
如果女友對這種淡妝效果還是不滿意,我們可以繼續添加化妝品類,睫毛膏、眼線、眉筆、腮紅等等等等,隻需要層層包裹起來,最終實作女友濃妝豔抹的夢想。

我們觀察這種裝飾器模式結構,是不是似曾相識呢?沒錯,其實裝飾器模式在JDK裡就有很多應用,比如Java IO包裡的衆多流處理類。
new BufferedReader(new InputStreamReader(new FileInputStream(filePath)));
當然,流處理類當然要比我們的例子複雜的多,但其基本思想和我們去繁就簡的例子異途同歸,這些對象就好像是俄羅斯套娃一樣層層包裹,層層裝飾,每套一層就會多出一些功能出來,我們更可以自由搭配,實作不同的組合功能。