設計模式學習筆記(三 裝飾模式)

2021-09-25 00:27:24 字數 3151 閱讀 7739

在許多設計中,可能需要改進類的某個物件的功能,而不是該類建立的全部物件,在這樣的情況下,就可以使用裝飾模式。

例如,麻雀類的例項(麻雀)能夠連續飛行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

com.liuzhen.three_decorator;

public

abstract

class

bird

(2)具體元件

對於本問題,具體元件是sparrow類,該類在實現

fly()

方法時,將該方法的返回值設定為

100。sparrow類的**如下:

package

com.liuzhen.three_decorator;

public

class sparrow extends

bird

}

(3)裝飾

本問題中,裝飾類是乙個抽象類,該類包含有乙個bird宣告的變數以儲存「被裝飾者」的引用。**如下:

package

com.liuzhen.three_decorator;

public

abstract

class decorator extends

bird

public

decorator(bird bird)

}

(4)具體裝飾

根據具體的問題,具體裝飾經常委託「被裝飾者」呼叫相應的方法。本問題中具體裝飾類是sparrowdecorator

類,該類的**如下:

package

com.liuzhen.three_decorator;

public

class sparrowdecorator extends

decorator

public

intfly()

/** elefly()方法訪問許可權設定為private,其目的是使得客戶程式只有呼叫fly方法才可以使用elefly方法

*/private

int elefly()

}

(5)具體

使用通過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...