在許多設計中,可能需要改進類的某個物件的功能,而不是該類建立的全部物件,在這樣的情況下,就可以使用裝飾模式。
例如,麻雀類的例項(麻雀)能夠連續飛行100公尺,如果用麻雀類建立了5只麻雀,那麼這5只麻雀都能連續飛行100公尺。假如想讓其中乙隻麻雀能夠連續飛行150公尺,那應當怎樣做呢?一種比較好的辦法就是給麻雀裝上智慧型電子翅膀,智慧型電子翅膀可以使得麻雀不使用自己的翅膀就能飛行50公尺。
裝飾模式是動態地擴充套件乙個物件的功能,而不需要改變原始類**的一種成熟模式。在裝飾模式中,「具體元件」類和「具體裝飾」類是該模式中最重要的兩個角色。「具體元件」類的例項稱作「被裝飾者」,「具體裝飾」類的例項稱為「裝飾者」。「具體裝飾」類需要包含有「具體元件」類的乙個例項的引用,以便裝飾「被裝飾者」。例如,前面所述的麻雀類就是「具體元件」類,而乙隻麻雀就是「具體元件」類的乙個例項,即是乙個「被裝飾者」,而安裝了電子翅膀的麻雀就是「具體裝飾」類的乙個例項,即安裝了電子翅膀的麻雀就是麻雀的「裝飾者」。
裝飾模式的結構中包括以下四種角色:
(1)抽象元件(component):抽象元件是乙個抽象類。抽象元件定義了「被裝飾者」需要進行「裝飾「的方法。
(2)具體元件(concretecomponent):具體元件是抽象元件的乙個子類,具體元件的例項稱為「被裝飾者「。
(3)裝飾(decorator):裝飾也是抽象元件的乙個子類,但裝飾還包含乙個抽象元件宣告的變數以儲存「被裝飾者「的引用。裝飾可以是乙個抽象類也可以是乙個非抽象類,如果是非抽象類,該類的例項稱為」裝飾者「。
(4)具體裝飾(concretedecorator):具體裝飾是裝飾的乙個非抽象子類,具體裝飾的例項稱為「裝飾者「。
裝飾模式結構的類圖如下所示:
(1)被裝飾者和裝飾者是松耦合關係。由於裝飾僅僅依賴於抽象元件,因此具體裝飾只知道它要裝飾的物件是抽象元件某乙個子類的例項,但不需要知道是哪乙個具體子類。
(2)裝飾模式滿足「開-閉原則「。不必修改具體元件,就可以增加新的針對該具體元件的具體裝飾。
(3)可以使用多個具體裝飾來裝飾具體元件元件的例項。
(1)程式希望動態地增強類的某個物件的功能,而又不影響到該類的其他物件。
(2)採用繼承來增強物件功能不利於系統的擴充套件和維護。
下面通過乙個簡單的例項,實現1.1概述中簡單例子:
假設系統中有乙個bird抽象類以及
bird
類的乙個子類
sparrow
。sparrow
類實現了
bird
類fly
方法,使得
sparrow
類建立的物件(麻雀)呼叫
fly()
方法能連續飛行
100公尺。
現在,使用者需要兩隻鳥,無論是那種鳥都可以,但必須分別能連續飛行150公尺和
200公尺。顯然,現有的系統無法向使用者提供這樣的
bird
物件,所以需要修改現有的系統。此處,使用裝飾者模式,即可實現不必修改系統的**,只需在系統中新增「裝飾」,該系統將可以建立出使用者需要的鳥。具體如下:
首先看一下本例項構建框架具體類和1.2模式的結構中類圖的對應關係,如下圖3所示:
圖3 具體編寫類及介面與類圖對應關係
(1)抽象元件
本問題中,抽象元件bird規定了具體元件需要實現方法,
bird
類的**如下:
package(2)具體元件com.liuzhen.three_decorator;
public
abstract
class
bird
對於本問題,具體元件是sparrow類,該類在實現
fly()
方法時,將該方法的返回值設定為
100。sparrow類的**如下:
package(3)裝飾com.liuzhen.three_decorator;
public
class sparrow extends
bird
}
本問題中,裝飾類是乙個抽象類,該類包含有乙個bird宣告的變數以儲存「被裝飾者」的引用。**如下:
package(4)具體裝飾com.liuzhen.three_decorator;
public
abstract
class decorator extends
bird
public
decorator(bird bird)
}
根據具體的問題,具體裝飾經常委託「被裝飾者」呼叫相應的方法。本問題中具體裝飾類是sparrowdecorator
類,該類的**如下:
package(5)具體com.liuzhen.three_decorator;
public
class sparrowdecorator extends
decorator
public
intfly()
/** elefly()方法訪問許可權設定為private,其目的是使得客戶程式只有呼叫fly方法才可以使用elefly方法
*/private
int elefly()
}
使用通過threeapllication類來具體實現上述相關類和介面,來實現介面卡模式的運用,其**如下:
package執行結果如下:com.liuzhen.three_decorator;
public
class
public
void
needbird(bird bird)
public
static
void
main(string args)
}
這只鳥能飛行150公尺這只鳥能飛行200公尺
設計模式學習筆記(三) 裝飾者模式
同系列文章 1.設計模式學習筆記 一 策略模式 2.設計模式學習筆記 二 觀察者模式 我又來了,續更 接下來的內容是觀察者模式的學習筆記 以下正文 裝飾者模式 動態地將責任附加到物件上。若要拓展功能,裝飾者提供了比繼承更加富有彈性的替代方案。先大概看看下面的幾張圖,幫助恢復記憶 類圖 思路 以咖啡為...
設計模式學習(三) 裝飾模式
在將模式之前,先對乙個oo設計原則掌握 對擴充套件開放和對修改關閉 無論如何,程式不能因為一些功能的修改就去該原來寫的,這樣只會越改越亂,因此,對修改遮蔽,和新增加的功能使用擴充套件的方式新增進去 裝飾者模式正可以做到這一點。這裡碰到的問題就是,軟體應對變化的能力,裝飾者模式提高了軟體的彈性,增加了...
《設計模式》學習筆記 裝飾模式
裝飾模式 decorator pattern 指的是在不必改變原類檔案和使用繼承的情況下,動態地擴充套件乙個物件的功能.它是通過建立乙個包裝物件,也就是裝飾來包裹真實的物件。pragma once include includeclass car class runcar public car pr...