1. 程式人生 > >設計模式(十一)裝飾者模式(Decorator)-結構型

設計模式(十一)裝飾者模式(Decorator)-結構型

裝飾者模式Decorator

在程式開發中,有時候開發人員會使用繼承來擴充套件物件的功能,使用者的需求是多變的,也就造成了使用繼承會造成程式碼的大範圍改動,其實擴充套件物件的功能,採用組合比繼承要好的多,當用戶需要變動時,只要將物件組合發生變化就可以了,不會大範圍地改動繼承的程式碼,此時就需要使用裝飾者模式。
裝飾者模式的本質就是為了擴充軟體的功能,但又不改變軟體原本的功能。就好比裝修房子一樣。
Decorator設計模式的結構如下:
   interface
          |
_ _ _ _ | _ _ _ _
|                    |
myClass Decorator
        _ _ _ _ _ | _ _ _ _ _
        |                         |
DecoratorA DecoratorB
採用裝飾者模式的主要目的也是為了使兩個關聯類之間能夠解耦,以方便新增一些新的功能。

實現原理圖

這裡寫圖片描述
裝飾者模式實現原理圖

如果不使用裝飾者模式,每次新增一個新的功能,都需要新建一個新類來繼承上一個類,從而獲取父類的全部屬性和方法,如果修改超類,則子類都需要做相應變化,不適合維護。而使用裝飾者模式,超類是一個介面,可以達到解耦的效果。

實現

假如是一個超市,它需要收銀,一般情況下就是商品的掃描價格,但是有時候也會搞活動,打特價之類。所以建立一個收銀類的介面Cash.java

package com.devin.decorator; 
/** 
 * @author 作者 E-mail: [email protected]
 * @version 建立時間:2015年4月26日 上午8:53:14 
 * 類說明 
 */
public interface Cash { public double getCash(String product); }

然後實現一個具體的收銀功能,CashImpl.java

package com.devin.decorator; 
/** 
 * @author 作者 E-mail: [email protected]
 * @version 建立時間:2015年4月26日 上午8:53:55 
 * 類說明 
 */
public class CashImpl implements Cash{
    @Override
    public double getCash
(String product) { return 100; } }

再定義一個收銀的裝飾類,CashDecorator.java的程式碼如下:

package com.devin.decorator; 
/** 
 * @author 作者 E-mail: [email protected]
 * @version 建立時間:2015年4月26日 上午8:54:38 
 * 類說明 
 */
public class CashDecorator implements Cash {
    private Cash cash;
    public CashDecorator(Cash cash){
        this.cash = cash;
    }

    @Override
    public double getCash(String product) {
        return cash.getCash(product);
    }

}

增加打折的新功能,該功能繼承收銀的裝飾類,RebateCash.java

package com.devin.decorator; 
/** 
 * @author 作者 E-mail: [email protected]
 * @version 建立時間:2015年4月26日 上午8:58:53 
 * 類說明 
 */
public class RebateCash extends CashDecorator {

    public RebateCash(Cash cash) {
        super(cash);
    }

    public double getCash(String product) {
        return super.getCash(product) * 0.1;

    }

}

增加只減折扣的功能,該功能繼承收銀的裝飾類,BacktrackCash.java

package com.devin.decorator; 
/** 
 * @author 作者 E-mail: [email protected]
 * @version 建立時間:2015年4月26日 上午8:58:53 
 * 類說明 
 */
public class BacktrackCash extends CashDecorator {

    public BacktrackCash(Cash cash) {
        super(cash);
    }

    public double getCash(String product) {
        return super.getCash(product) -0.1;
    }

}

測試

客戶端測試,既要進行折扣,又要進行減折扣:

package com.devin.decorator; 
/** 
 * @author 作者 E-mail: [email protected]
 * @version 建立時間:2015年4月26日 上午9:04:59 
 * 類說明 
 */
public class Client {
    public static void main(String[] args) {
        Cash cash = new CashImpl();
        Cash rebateCash = new BacktrackCash(new RebateCash(cash));
        System.out.println("巧克力的價格是:" + rebateCash.getCash("巧克力"));
    }

}

測試結果:

巧克力的價格是:9.9

應用

Java的I/O流
Reader Writer
BufferedReader BufferedWriter
BufferedInputStream BufferedOutputStream

相關推薦

設計模式裝飾模式Decorator-結構

裝飾者模式Decorator 在程式開發中,有時候開發人員會使用繼承來擴充套件物件的功能,使用者的需求是多變的,也就造成了使用繼承會造成程式碼的大範圍改動,其實擴充套件物件的功能,採用組合比繼承要好的多,當用戶需要變動時,只要將物件組合發生變化就可以了,不會大

設計模式裝飾模式Decorator

不知道 operation 總結 界面 都是 per @override stat override   裝飾者模式針對的問題是:對一個結構已經確定的類,在不改變該類的結構的情況下,動態增加一些功能。   一般來說,都是對一些已經寫好的架構增加自己的功能,或者應對多種情況,

headfirst設計模式3裝飾模式

其中 拖延 穩定 放棄 等等 logs headfirst 自己的 定義 序 好久沒寫設計模式了,自從寫了兩篇之後,就放棄治療了,主要還是工作太忙了啊(借口,都是借口),過完年以後一直填坑,填了好幾個月,總算是穩定下來了,可以打打醬油了。 為什麽又重新開始寫設計模式呢?學習

設計模式-14裝飾模式 swift版

實現 info 有一個 istview listview 接口 tor true lis 一,概念   裝飾者模式(Decorator):動態地為一個對象添加一些額外的職責,若要擴展一個對象的功能,裝飾者提供了比繼承更有彈性的替代方案。   多組合,少繼承 二,UML圖

JAVA設計模式詳解----------裝飾模式

今天LZ帶給大家的是裝飾者模式,提起這個設計模式,LZ心裡一陣激動,這是LZ學習JAVA以來接觸的第一個設計模式,也許也是各位接觸的第一個設計模式。記得當初老師在講IO的時候就提到過它:“是你還有你,一切拜託你。”沒錯,這就是裝飾者模式最簡潔的定義了。下面LZ引出標準的定義(

設計模式裝飾模式

參考: 1. 概念解析 裝飾者模式:在不改變原類檔案和繼承的情況下,動態的拓展一個物件的功能,通過建立一個包裝物件,也就是裝飾來包裹真實的物件。 特點: 裝飾物件和真實物件有相同的介面,這樣客戶端物

設計模式——裝飾模式Decorator Pattern

    裝飾者模式:動態將責任附加到物件上,要拓展功能,提供了比繼承更有彈性的方案。 很多文章也是拿了書上的例子來講,同時寫到,有的調料裝飾者都必須實現 getDescription() 大家可以先考慮下,稍後我們會說。最後都是沒說,還有思考的

《JavaScript設計模式與開發實踐》模式12—— 裝飾模式

在傳統的面嚮物件語言中,給物件新增功能常常使用繼承的方式,但是繼承的方式並不靈活, 還會帶來許多問題:一方面會導致超類和子類之間存在強耦合性,當超類改變時,子類也會隨之 改變;另一方面,繼承這種功能複用方式通常被稱為“白箱複用”,“白箱”是相對可見性而言的, 在繼承方式中,超類的內部細節是對子類可見的,

設計模式Decorator Pattern——裝飾模式

一、裝飾者模式簡介在HeadFirst 介紹裝飾者模式的導論中,這麼介紹裝飾者模式給愛用繼承的人一個全新的設計眼界那麼更通俗講,什麼是裝飾者模式呢?裝飾者,包裝原有的物件,使之變成具有包裝著功能的新事物。舉個栗子,你去一家麵館吃麵,這是一家專門做麵食的餐館,有面條,湯料,獅子

設計模式C#——裝飾模式

推薦閱讀:  我的CSDN  我的部落格園  QQ群:704621321       在一款戰鬥類的遊戲中,隨著故事情節的

Head First設計模式裝飾模式

星巴茲咖啡準備更新訂單系統,以合乎他們的飲料供應需求。 他們原先的類設計為: 這樣的訂單系統沒有辦法考慮到咖啡調料的部分,把加入不同調料的咖啡看做不同的類會導致類爆炸(每個類的cost方法計算出咖啡加調料的價錢): 很明顯,這樣的系統難以維護,一旦牛奶的價錢上揚或新增一

設計模式—— 裝飾模式

由於之前看的容易忘記,因此特記錄下來,以便學習總結與更好理解,該系列博文也是第一次記錄,所有有好多不完善之處請見諒與留言指出,如果有幸大家看到該博文,希望報以參考目的看瀏覽,如有錯誤之處,謝謝大家指出與留言。 一、咖啡館訂單系統專案 咖啡館訂單系統專案: 咖啡館訂單

C# 設計模式裝飾模式unity演示

1、引言   在軟體開發中,我們常常碰到想要給一類物件新增不同的功能。比如遊戲中,一個遊戲角色可以穿戴不同的物品,來不同的外觀。這就是我們常說的面板像:靴子、護腕、武器、腰帶、頭盔、盔甲等,這樣使玩家有了不同的屬性。為了解決這個問題,我們可以使用裝飾

設計模式3裝飾模式

number 設計模式 bsp bubuko override closed des ase spa 我們到咖啡店喝咖啡的時候,往往會根據各自的口味去選擇咖啡和各種配料,比如咖啡可以選擇綜合、深焙、低咖啡因、濃縮,配料可以選搭牛奶、摩卡、豆漿、奶泡。這個情境下就可以使用裝飾

JS實現AOP面向切面程式設計--裝飾模式

1、AOP:主要作用是把一些跟核心業務邏輯模組無關的功能抽離出來,這些跟業務邏輯無關的功能通常包括日誌統計、安全控制、異常處理等。把這些功能抽離出來之後,再通過“動態織入”的方式參入業務邏輯模組中。 2、AOP好處 保證業務邏輯模組的純淨和高內聚性 方便複用日誌統計等功

設計模式C++實現二:中介模式

中介者模式(Mediator):用一箇中介物件來封裝一系列的物件互動。中介者是各物件不需要顯式地相互引用,從而使其耦合鬆散,而且可以獨立地改變他們之間的互動。 中介者模式很容易在系統中應用,也很容易在系統中誤用。當系統出現多對多互動複雜的物件群是,不要急於使用中介者模式,而

設計模式-第四篇中介模式

1. 定義       中介者模式的英文定義:Define an object that encapsulates how a set of objects interact.Mediator promotes loose couping by keeping objects

設計模式建造模式

用程式畫一個小人,這在遊戲程式裡非常常見。現在簡單一點,要求是小人要有頭、身體、兩手、兩腳就可以了。 第一版  Pen p = new Pen (Color.Yellow); Graphics gThin = pictureBox1.CreateGraphics();

一個故事貫穿設計模式中介模式

   這裡記錄的是中介者模式。  在解耦上面具有重要的意義。 包結構: 類結構: 測試入口: package com.automannn.design_mode.mediator.test; import com.automannn.design

設計模式中介模式

中介者模式(Mediator):用一箇中介物件來封裝一系列的物件互動。中介者使各物件不需要顯示地相互引用,從未使其耦合鬆散,而且可以獨立地改變他們之間的互動 類圖的來源: public abstract class Mediator { public