裝飾者模式

2021-09-24 08:29:51 字數 3393 閱讀 4054

裝飾者模式

定義在不改變原有物件的基礎之上,將功能附加到物件上。提供了比繼承更有彈性的替代方案(擴充套件原有物件功能)

型別結構型

適用場景

擴充套件乙個類的功能或者給乙個類新增附加職責

給乙個物件動態的新增功能,或動態撤銷功能。

優點繼承的有力補充,比繼承靈活,不改變原有物件的情況下給乙個物件擴充套件功能。(繼承在擴充套件功能是靜態的,必須在編譯時就確定好,而使用裝飾者可以在執行時決定,裝飾者也建立在繼承的基礎之上的)

通過使用不同裝飾類以及這些類的排列組合,可以實現不同的效果。

符合開閉原則

缺點會出現更多的**,更多的類,增加程式的複雜性。

動態裝飾時,多層裝飾時會更複雜。(使用繼承來拓展功能會增加類的數量,使用裝飾者模式不會像繼承那樣增加那麼多類的數量但是會增加物件的數量,當物件的數量增加到一定的級別時,無疑會大大增加我們**除錯的難度)

裝飾者相關的設計模式

裝飾者模式關注的是物件的動態新增功能。**模式關注的是對物件的控制訪問,對它的使用者隱藏物件的具體資訊。

裝飾者模式和被裝飾的類要實現同乙個介面,或者裝飾類是被裝飾的類的子類。 介面卡模式和被適配的類具有不同的介面。

按照我部落格的國際慣例,下面開始看**,看**之前首先假設乙個應用場景吧假設我們現在在路邊攤看到乙個賣煎餅果子的,現在想買煎餅果子,煎餅果子一般的話都是可以加雞蛋加香腸什麼的,好那我們就來模擬一下加在煎餅果子上加東西的操作。 首先我們看一下使用繼承的方式怎麼實現。

建立乙個煎餅果子類

public

class

battercake

protected

intcost()}

複製**

加雞蛋類,我們讓加雞蛋類繼承煎餅果子類

public

class

battercakewithegg

extends

battercake

@override

public

intcost()}

複製**

加香腸類,同樣的繼承煎餅果子類。

public

class

battercakewitheggsausage

extends

battercakewithegg

@override

public

intcost()}

複製**

測試類

public

class

decoratorv1test

}複製**

輸出結果

煎餅 銷售**:8

煎餅 加乙個雞蛋 銷售**:9

煎餅 加乙個雞蛋 加一根香腸 銷售**:11

複製**

這樣做有個問題,什麼問題呢?假設我們現在要加2個雞蛋呢?糟糕我們沒寫加2個雞蛋的類,如果還有3個4個什麼的那是不是就要類**了。下面我們使用裝飾者模式實現一下。

首先我們定義乙個抽象的煎餅果子

public

abstract

class

abattercake

複製**

實體煎餅果子類,實體煎餅果子繼承了抽象煎餅果子類。

public

class

battercake

extends

abattercake

@override

protected

intcost()}

複製**

裝飾父類,這裡也是可以使用抽象類,等會兒我們再說什麼時候使用抽象類什麼時候使用實體類。注意構造器和這個裡面的花費、描述方法的寫法。這裡注入乙個抽象煎餅類的物件。我們的獲取描述花費的操作都委託抽象煎餅類來執行,為什麼要這麼做可以去看看我之前的文章依賴倒置原則。

public

class

abstractdecorator

extends

abattercake

@override

protected string getdesc

() @override

protected

intcost()}

複製**

雞蛋的裝飾類,這裡注意他的構造器,引數是父類的物件抽象煎餅類物件,這裡獲取描述和花費方法都是呼叫了父類的方法。

public

class

eggdecorator

extends

abstractdecorator

@override

protected string getdesc

() @override

protected

intcost()}

複製**

香腸裝飾類

public

class

sausagedecorator

extends

abstractdecorator

@override

protected string getdesc

() @override

protected

intcost()}

複製**

最後是測試類,建立乙個實體煎餅果子類並賦值給抽象煎餅果子類,然後將這個父類物件注入裝飾類,再把得到的物件賦值給建立的抽象物件。

public

class

decoratorv2test

}複製**

輸入結果

煎餅 加乙個雞蛋 加乙個雞蛋 加一根香腸 銷售**:12

複製**

最後我們來說說裝飾父類什麼時候使用抽象類。一般當我們需要在具體的類中都需濤執行一些特定的操作時。我們一般就會使用抽象類,並定義抽象方法。

public

abstract

class

abstractdecorator

extends

abattercake

//定義每個抽象類的獨特方法

protected

abstract

void

dosomething();

@override

protected string getdesc

() @override

protected

intcost()}

複製**

裝飾者模式

裝飾者模式 動態地將責任附加到物件上。若要擴張功能,裝飾者提供了比繼承更有彈性的替代方案。裝飾者可以在所委託被裝飾者的行為之前或之後,加上自己的行為,以達到特定的目的。裝飾者與被裝飾者物件具有相同的超型別。include include using namespace std class bever...

裝飾者模式

裝飾者模式,是在不改變原類檔案和使用繼承的情況下,動態地擴充套件乙個物件的功能。它是通過建立乙個包裝物件,也就是裝飾來包裹真實的物件。裝飾者模式中的角色 1 被裝飾者抽象component,是乙個介面或抽象類,就是定義最核心的物件,也是最原始的物件,這個類是需要裝飾類的基類。2 被裝飾者具體實現co...

裝飾者模式

裝飾者模式 裝飾者模式的好處是便於擴充套件,對乙個東西不管怎麼變,只需要找到相應的元件去改變它 1.如何組裝在一起 建立主題 packetbodycreator body new packetbodycreator 建立header packethtmlheadercreator html new ...