1. 程式人生 > >Java設計模式(9)----------裝飾器模式

Java設計模式(9)----------裝飾器模式

tor 畫框 imp 橋接 好的 找到 strac 想是 bstr

1、介紹

裝飾器模式是一種結構型的設計模式。使用該模式的目的是為了較為靈活的對類進行擴展,而且不影響原來類的結構。有同學說可以通過繼承的方式進行實現啊,沒錯,繼承的確可以實現,但是繼承的成本相對比較高,而且如果涉及到擴展多個功能的話,繼承實現起來的成本較大。

裝飾器模式的思想是,對原來的類進行一層封裝,通過依賴實現擴展。但是裝飾器的依賴有兩個比較重要的特點。

第一,裝飾器的抽象類,依賴的是原來類的接口。裝飾器的實現類與原本的類之間,不會存在耦合的現象,兩個類可以各自進行對應的變化。這一點與橋接模式是相同的。

第二,裝飾器的抽象類會同時繼承原來類的接口,從而保證裝飾器的實現類具有與原來的類一樣的方法,只是裝飾器實現類的方法有新的擴展。可以理解為對原有類的某種功能或者特性的加強。這樣產生的效果就是,從使用者的角度來看,會更加的便捷,因為原來的類與裝飾器類具有一樣的方法,真是其中實際的功能和作用進行了加強。

裝飾器模式的使用場景,抽象來說就是需要擴展類但是又不想引入子類,或者也可以根據字面的含義,能與裝飾或者功能加強有關的場景。比如說,一張畫,是可以欣賞的,但是沒有辦法掛到墻上。那麽我們可以找一個相框(裝飾器實現類),將畫放到相框中,之後就可以把這個帶相框的畫掛到墻上了。再比如說,我們買了一張床,就可以在上邊睡覺了。但是我們希望睡的更加舒服,所以需要在床上增加一個裝飾,比如墊上床墊,加上枕頭,蓋上床單。裝飾之後,它依然有承載睡覺的屬性。

2、案例

2.1、背景

就舉一個上文提到的畫與畫框的例子。為了提高節操,哦不,是情操,本同學需要觀賞(接口)一下工藝品。談到觀賞,我們可以觀賞油畫和水墨畫(接口實現類

)。但是油畫和水墨畫無法掛在墻上讓眾人欣賞,所以我們希望找一個相框(裝飾器抽象類),將畫放進去,然後掛起供人欣賞(裝飾或者功能加強)。之後,我們終於找到了一個木質的相框(裝飾器實現類),裝飾之後,具有更好的觀賞效果。

2.2、實現

1)定義觀賞的接口

public interface Look {
    public String LookAtPic();
}

2)定義觀賞的實現類

public class InkPic implements Look
{
    @Override
    public String LookAtPic()
    {
        return "欣賞水墨畫";
    }
}
public class OilPic implements Look
{
    @Override
    public String LookAtPic() {
        return "欣賞油畫";
    }
}

3)定義裝飾器抽象類

public abstract class PicDecorator implements Look
{
    private Look look;
 
    public Look getLook() {
        return look;
    }
 
    public void setLook(Look look) {
        this.look = look;
    }
 
    public PicDecorator(Look look) {
        this.look = look;
    }
 
    @Override
    public abstract String LookAtPic();
}

4)裝飾器實現類

public class WoodPicDecorator extends PicDecorator
{
    public WoodPicDecorator(Look look) {
        super(look);
    }
 
    @Override
    public String LookAtPic() {
        return this.getLook().LookAtPic() + ",木質相框";
    }
}

5)運行

public class Test
{
    public static void main(String[] args)
    {
        OilPic oilPic = new OilPic();
        System.out.println(oilPic.LookAtPic());
 
        WoodPicDecorator woodPicDecorator = new WoodPicDecorator(oilPic);
        System.out.println(woodPicDecorator.LookAtPic());
 
        InkPic inkPic = new InkPic();
        System.out.println(inkPic.LookAtPic());
 
        woodPicDecorator = new WoodPicDecorator(inkPic);
        System.out.println(woodPicDecorator.LookAtPic());
    }
}

5)結果

欣賞油畫
欣賞油畫,木質相框
欣賞水墨畫
欣賞水墨畫,木質相框

Process finished with exit code 0

3、總結

裝飾器模式的關鍵代碼有兩點:第一,裝飾器抽象類依賴原接口;第二,裝飾器抽象類實現原接口。

優點:低成本擴展類的方法(功能加強)

缺點:這種方法非常精巧,非要找一個缺點的話,那就是精巧的東西一般都不太好理解。

Java設計模式(9)----------裝飾器模式