背景是有一家星巴茲咖啡店,由於客源充足,所以決定重新設計他們的收費系統,以前的收費系統中只定義了乙個表示飲料的beverage的基類,它裡面定義了乙個cost的方法用來計算飲料的花費,但是對於星巴茲來說他們的飲料的種類實在太多了,不能就每一種飲料就建立乙個子類,型別**!
所以要進行一番設計,來改變目前這種型別**的局面。
利用繼承設計子類的行為,實在編譯時靜態決定的,而且所有的子類都會繼承到相同的行為,如果能夠利用組合的做法擴充套件物件的行為,就可以在執行時動態的進行擴充套件。通過動態的組合物件,可以寫新的**新增新功能,而無須修改現有**。既然沒有改變現有**,那麼引進bug或者產生意外***的機會就會變得少很多。
設計原則:類應該對擴充套件開放,對修改關閉(開閉原則)
我們的目標是允許類容易擴充套件,在不修改現有**的情況下,就可搭配新的行為,如果實現這樣的目標,有什麼好處呢?這樣的設計具有彈性可以應對改變,可以接受新的功能來應對改變的需求。
遵循開放-關閉原則,通常會引入新的抽象層次,增加**的複雜度。需要把注意力集中在設計中最有可能改變的地方,然後應用開放-關閉原則。
按照上述原則分析需求,首先,我們把飲料當作主體,而各種調料當作裝飾,用調料來裝飾飲料,如果顧客想要摩卡和奶泡咖啡,那麼要做的是:
①準備乙個咖啡物件。
②用摩卡裝飾他。
③用奶泡裝飾他。
④呼叫cost方法。
在給出具體的做法之前,先給出裝飾者模式的定義:動態的將責任附加到物件上,如要擴充套件功能,裝飾者提供了比繼承更有彈性的替代方案。
簡單的來說,就是用decorator來裝飾concretecomponent,因為他們都具有相同的基類,達到了一種「型別匹配」的目的,而不是用來獲取基類的行為。到時候,相關的型別之間能夠被互相取代。
當我們將裝飾著和元件組合時,就是在加入新的行為,所得到的新的行為,並不是繼承得來的,而是有組合物件得來的。如果依賴繼承,那麼類的行為就是在編譯時靜態決定的。換句話說,行為如果不是來自基類,就是來自子類覆蓋後的版本。反之,如果利用組合,可以把裝飾著混合著用,而且是在執行時。
而且還可以在任何時候實現新的裝飾者增加新的行為,如果依賴繼承,每當需要新行為時,還得修改現有的**。
按照上面給的uml類圖,首先從beverage下手,這代表了乙個component,所有的型別都直接或者間接的從它繼承,來獲取型別的一致性。而這是decorator的關鍵。
public接著,定義乙個concretecomponent:abstract
class
beverage
public
abstract
double
cost();
}
public由於在beverage中cost是抽象方法,所以要在子類中去override。sealed
class espresso:beverage//
代表某種咖啡
public
override
double
cost()
}
再定義乙個裝飾者的基類,也就是類圖上的condimentdecorator:
public然後就是定義具體的裝飾類:abstract
class
condimentdecorator : beverage
}
public然後測試一下:class mocha:condimentdecorator//
摩卡,一種咖啡的「裝飾」
public
override
string
description
public
override
double
cost()
}
class從上述**可以看到這種裝飾的行為正是依賴了統一的基類帶來的型別的一致性,也證實了我們前面所言非虛。而在具體類的內部,根據物件的組合進一步擴充套件了物件的功能。由於物件組合上是針對抽象(抽象類)進行程式設計,所以很容易通過ioc容器來進行控制反轉的實現。program
,cost is ");
beverage=new
mocha(beverage);//進一步裝飾
console.writeline($
",cost is ");
beverage=new
mocha(beverage);//進一步裝飾
console.writeline($
",cost is ");
console.readkey(); }}
c 設計模式之裝飾者模式
include 公共介面 class component 需要被裝飾的物件 class concretecomponent public component void operation 裝飾a類 class concretedecoratora public decorator 裝飾b類 clas...
c 設計模式之裝飾者模式
include 公共介面 class component 需要被裝飾的物件 class concretecomponent public component void operation 裝飾a類 class concretedecoratora public decorator 裝飾b類 clas...
c 設計模式之裝飾者模式
裝飾者模式動態地將責任附加到物件上,如果要擴充套件功能,裝飾者模式提供了比繼承更有彈性的替代方案.裝飾者模式有一群裝飾者類,這些類包裝具體的類元件 class component 公共抽象類 class concretecomponent public component 具體的類 class de...