設計模式筆記 10 裝飾模式(結構型)

2021-09-05 22:09:50 字數 2358 閱讀 6497

動態地給乙個物件增加一些額外的職責。就增加功能而言,decorator模式比生成子類更為靈活。

首先來看乙個小例子,假如我們需要給遊戲開發一種坦克,除了各種不同型號的坦克外,還希望在不同的場合來給坦克增加以下的一種或多種功能:比如紅外線夜視功能、水陸兩棲功能、gps定位功能等。通常做法如下:

/// /// 

抽象坦克

///

public abstract class

tank

//型號

public class

t50 : tank

public class

t60 : tank

public class

t70 : tank

//在不同場合下的各種功能都抽象為介面,

//如果某種型號的坦克需要某種功能就繼承該功能介面

//下面的ia ib ic 為功能a b c的介面

/// ///

有a功能的t50型號

///

public class

t50a : t50, ia

/// ///

有a b兩種功能的t60型號

///

public class

t60ab : t60, ia, ib

/// ///

有a b c三種功能的t70型號

///

public class

t70abc : t70, ia, ib, ic

上面描述的問題的根源在於我們「過多地使用了繼承來擴充套件物件的功能」,由於繼承為賴幸引入了靜態特質,使得這種擴充套件方式缺乏靈活性,並且隨著子類的增多(擴充套件功能的增多),各種子類的組合(擴充套件功能的組合)會導致更多子類的膨脹(多繼承)。那麼如何使「物件功能的擴充套件」能夠根據需要來動態地實現,同時避免「擴充套件功能的增多」帶來的子類膨脹問題,從而使得任何「功能的變化」所導致的影響減為最低呢?這就需要用到裝飾模式(decorator)。下面先來看下裝飾模式的結構圖:

component:對應上面例子中的tank。

concretecomponent:對應坦克的型號 t50 t60 t70等。

decorator concretedecoratora concretedecoratorb 這三個類就是接下來要實現了。

public abstract class 

decorator : tank

public override void shot()

public override void run()

}public class

concretedecoratora : decorator

public override void shot()

public override void run()

}public class

concretedecoratorb : decorator

public override void shot()

public override void run()

}public class

concretedecoratorc : decorator

public override void shot()

public override void run()

}

客戶端的呼叫

public class 

}

通過採用組合、而非繼承的手法, 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模式應用的要點在於解決「主體類在多個方向上的擴充套件功能」——是為「裝飾」的含義。

返回開篇(索引)

結構型設計模式 裝飾模式

裝飾模式動態地給乙個物件新增一些額外的職責,就增加功能來說,它比生成子類更靈活。也可以這樣說,裝飾模式把複雜類中的核心職責和裝飾功能區分開了,這樣既簡化了複雜類,有去除了相關類中重複的裝飾邏輯。裝飾模式沒有通過繼承原有類來擴充套件功能,但卻達到了一樣的目的,而且比繼承更加靈活,所以可以說裝飾模式是繼...

結構型設計模式 裝飾模式

先列舉乙個生活中的場景。假如我們買了一套房 買不起。但是是乙個毛胚房 指沒有任何裝修的房子 只能住。那麼我們為了讓房子變得溫馨舒適,就要進行裝修了,這樣沒有改變房子原本用來居住的功能,還增加了很多新的功能 比如做飯 那麼這一期的裝飾模式就是基於這樣的動機,在不改變原有功能的情況下新增新功能。那麼給乙...

設計模式 裝飾者模式 結構型

裝飾者模式 動態的給一些物件新增一些職能,就增加功能來說,裝飾者比生成子類更靈活。模型圖 public abstract class componentpublic class concretecomponet extends component public abstract class deco...