設計模式 — 裝飾者模式(The decorator pattern)

來源:互聯網
上載者:User

 設計模式 ---  裝飾者模式 (The decorator pattern)

ok .. 我們繼續第二個模式 ---  裝飾者模式

我們繼續以前的書寫習慣,按照下面的順序。。

1. 什麼是裝飾者模式

還是按照書上的定義,裝飾者模式 ---  為一個對象動態添加額外的響應性。裝飾者模式可以為子類的擴充功能添加靈活的改變能力(The Decorator Pattern attaches additional reponsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.)。

這樣講,連我自己都覺得抽象。。呵呵。那我舉們個例子先。

(1)如果我們有第一種飲料 --- 咖啡,價格20塊。

(2)然後我們有第二種飲料 --- 加糖咖啡, 糖要5塊,所以總價格25塊。

那我們怎麼描述這兩種飲料的之間的關係呢?如果我們使用裝飾者來處理的話,我們可以這樣描述它們的關係:

我們定義一個飲料介面,然後首先咖啡類實現這個介面,然後它的價格方法返回20塊。

我們再定義加糖咖啡類,同樣實現飲料介面,因為它也是飲料。但是它封裝了咖啡類。然後它的價格方法,首先直接調用咖啡的價格,因為它封裝了咖啡嘛。然後再加上自己的價格就好了。

估計這樣講還是很迷惑,沒事。我們繼續往下分析。。。

2. 裝飾者模式的用途

根據上面的描述,那麼裝飾者就是在我們已經有一套既存的系統在啟動並執行時候,然後我們需要增強它的功能。就像我們本來賣咖啡,然後突然有天我們需要賣加糖的咖啡,我們就可以不用修改原來咖啡對象的代碼,直接裝飾原來的咖啡對象就好了。

3. 裝飾者模式的用法

ok ....... 講完裝飾者模式的定義和用途後,我們再詳細詳細講講到底怎麼用裝飾者。。

還是繼續上面例子,如果我們之前有一個系統裡面有個咖啡類,但是我們的boss打算推出一種新的飲料種類,好吸引顧客,也就是加糖的咖啡。

那我們這些程式員怎麼辦呢,老闆的吩咐我們肯定要做的。我們肯定是希望在不要修改原有代碼的基礎上,來添加新的功能。

我們可以分以下幾步完成:

(1) 首先我們來假定我們原來有個飲料介面:
public interface Drink{

    public int getPrice();

}

然後我們的咖啡類也許是這樣實現的

public class Coffee implements Drink{

     public int  getPrice(){

              return 20;

      }

}

(2) ok ... 一切分析完畢,我們來添加新的飲料 --- 加糖咖啡

public class SugarCoffer implements Drink{

     private Drink drink;

     public SugarCoffer(){}

      public SugarCoffer(Drink drink){

              /// 這裡我們傳入咖啡對象

              this.drink = drink;

      }

       public int getPrice(){

              return ownPrice() + drink.getPrice();

       }

       private int ownPrice(){

               return 5;

      } 

}

(3) 由於加糖咖啡也是實現了飲料介面,所以之前可以用咖啡對象的地方,我們都可以用加糖咖啡來代替。因為我們是面向介面編程,而不是物件導向編程。。。

如果有天我們的變態老闆哪天又要添加新的飲料,比如,要推出冰爽加糖咖啡,冰爽費是10塊。那麼應該是35塊錢。

我們可以這樣依葫蘆畫瓢。

public class IceSugarCoffer implements Drink{

       private Drink drink;

      public IceSugarCoffer(){}

       public IceSugarCofffer(Drink drink){

             ///這裡我們可以傳入加糖咖啡對象

              this.drink = drink;

      }

      public int getPrice(){

            return ownPrice()  + drink.getPrice();

      }

      private int ownPrice(){

            return 10;

    }

}

4. JDK 裡面的裝飾者例子

在JDK原始碼裡面,我們可以發現使用裝飾者模式的地方還是蠻多的,比如Java檔案讀寫類的實現就大量採用了裝飾者模式。

比如:

InputStream

 

 

FileInputStream                                    StringBufferInputStream                                 ByteArrayInputStream                                                                        FilterInputStream

這裡下面行的類,比如FilterInputStream等等能就是裝飾InputStream, 它們共同的介面是Closeable。

就像FilterInputStream的構造方法是這樣實現的:

protected FilterInputStream(InputStream in) {
           this.in = in;
 }

很明顯,這裡FilterInputStream封裝了InputStream這個對象。

5. 最後總結裝飾者模式

裝飾者模式 ---  為你的子類裝飾眼睛(Desgin eye for the inheritance guy)。。 因為裝飾者模式可以動態隨時注入任何一個裝飾者到系統裡面(因為它們是實現了相同的介面)。它就像有眼睛的子類一樣,隨時找到最合適的裝飾者。 //////  ^^

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.