10. decorator 裝飾(結構型模式)
李建忠
上海祝成科技高階培訓講師
子類復子類,子類何其多
假如我們需要為遊戲中開發一種坦克,除了各種不同型號的坦克外,我們還希望在不同場合中為其增加以下一種或多種功能:比如紅外線夜視功能(ia),比如水陸兩棲功能(ib),比如衛星定位功能(ic)等等。
// 抽象坦克
public abstract class tank
//各種型號
public class t50: tank
public class t75: tank
public class t90: tank
//各種不同功能的組合
public class t50a: t50, ia
public class t50b: t50, ib
public class t50c: t50, ic
public class t50ab: t50, ia, ib
public class t50bc: t50, ib, ic
public class t50abc: t50, ia, ib, ic
動機(motivation)
上述描述的問題根源在於我們「過度地使用了繼承來擴充套件物件的功能」,由於繼承為型別引入的靜態特質,使得這種擴充套件方式缺乏靈活性;並且隨著子類的增多(擴充套件功能的增多),各種子類的組合(擴充套件功能的組合)會導致更多子類的膨脹(多繼承)。
如何使「物件功能的擴充套件」能夠根據需要在執行時動態地實現?同時避免「擴充套件功能的增多」帶來的子類膨脹問題?從而使得任何「功能擴充套件變化」所導致的影響將為最低?
意圖(intent)
動態地給乙個物件增加一些額外的職責。就增加功能而言,decorator模式比生成子類更為靈活。
——《設計模式》gof
例說decorator應用codes in vs.net
結構(structure)
decorator模式的幾個要點
通過採用組合、而非繼承的手法,decorator模式實現了在執行時動態地擴充套件物件功能的能力,而且可以根據需要擴充套件多個功能。避免了單獨使用繼承帶來的「靈活性差」和「多子類衍生問題」。
component類在decorator模式中充當抽象介面的角色,不應該去實現具體的行為。而且decorator類對於component類應該透明——換言之component類無需知道decorator類,decorator類是從外部來擴充套件component類的功能。
decorator類在介面上表現為is-a component的繼承關係,即decorator類繼承了component類所具有的介面。但在實現上又表現為has-a component的組合關係,即decorator類又使用了另外乙個component類。我們可以使用乙個或者多個decorator物件來「裝飾」乙個component物件,且裝飾後的物件仍然是乙個component物件。
decorator模式並非解決「多子類衍生的多繼承」問題,decorator模式應用的要點在於解決「主體類在多個方向上的擴充套件功能」——是為「裝飾」的含義。
.net框架中的decorator應用
推薦資源
《設計模式:可復用物件導向軟體的基礎》gof
《物件導向分析與設計》grady booch
《敏捷軟體開發:原則、模式與實踐》robert c. martin
《重構:改善既有**的設計》 martin fowler
《refactoringto patterns》joshuakerievsky
Decorator裝飾設計模式(結構型)
第八個設計模式 意圖 動態地給乙個物件新增一些額外的職責。有時候我們需要給某個物件而不是整個類新增一些功能。適用性 結構 參與者 component 定義乙個物件介面,可以給這些物件動態地新增職責。concretecomponent 定義乙個物件,可以給這個類的物件新增一些職責 decorator ...
裝飾者模式(Decorator) 結構型
1 基礎知識 定義 在不改變原有物件的基礎上,將功能附加到物件上即動態地給乙個物件新增一些額外的職責。特徵 提供了比繼承更有彈性的替代方案。本質 動態組合。使用場景 擴充套件乙個類的功能或給乙個類新增附加的職責 動態給乙個物件新增功能,這些功能還可以動態撤銷。優點 比繼承更加靈活,繼承是靜態的在設計...
裝飾模式 Decorator
裝飾模式 decorator 動態地給乙個物件新增一些額外的職責,就增加功能來說,裝飾模式比生成子類更加靈活。其中component定義了乙個物件介面,可以給這些物件動態的新增職責 concretecomponent是定義了乙個具體的物件,也可以給這個物件新增一些職責 decorator裝飾抽象類,...