裝飾模式(decorator):動態地給乙個物件新增一些額外的職責,就增加功能來說,裝飾模式比生成子類更為靈活。
上圖為裝飾模式的結構圖,component定義乙個物件介面可以給這些物件動態地新增職責。concretecomponent是定義了乙個具體的物件,也可以給這個物件新增一些職責(concretecomponent主要就是作為乙個具體的物件存在)。decorator,裝飾抽象類,繼承自component,從外類擴充套件component類的功能,相對於component來說無需知道decorator存在。concretedecorator就是具體的裝飾物件,起到給component新增職責的功能。
p.s:如果只有乙個concretecomponent而沒有抽象的component類,那麼decorator類可以是concretecomponent的乙個子類。同樣道理,如果只有乙個concretedector類(即只有乙個具體的裝飾類),那麼就沒必要單獨建立乙個decorator類,可以把decorator和concretedecorator的職責合併。
從上圖中可以看到裝飾模式的四要素:
1.裝飾的介面即component;
2.裝飾的具體物件concretecomponent,用於實現新增職責的功能;
3.抽象的裝飾類,同時繼承自component;
4.具體的裝飾類,繼承自抽象的裝飾類。
component:
abstractconcretecomponent:class
component
classdecorator抽象裝飾類:concretecomponent:component
}
abstract具體裝飾類:class
decorator : component
//////
設定component
/// ///
public
void
setcomponent(component component)
//////
重寫operation方法,實際執行的是component的operation
/// public
override
void
operation()}}
class呼叫方法:concretedecoratora:decorator
}class
concretedecoratorb : decorator
}class
concretedecoratorc : decorator
}
concretecomponent component = new呼叫效果如下:concretecomponent();
concretedecoratora c1 = new
concretedecoratora();
concretedecoratorb c2 = new
concretedecoratorb();
c1.setcomponent(component);
c2.setcomponent(c1);
c2.operation();
裝飾的過程:先定義了具體的component類concretecomponent,然後使用concretedecoratora 的例項化物件c1來包裝component,然後用concretedecoratorb的物件c1來包裝c1,最終執行c2的operation方法。其實裝飾模式最主要的是使用setcomponent來對物件進行包裝的。這樣每個裝飾物件的例項就和如何使用這個物件分離開了,每個裝飾物件只關心如何被新增到物件鏈當中。
整個過程是層層傳遞的,最終會先執行被傳遞的那個component物件(也可以說是具體的裝飾物件),整個的過程主要通過setcomponent進行完成,以及在具體物件的operation中執行base的操作(這樣才可以執行到傳遞的component的行為,其實就是乙個繼承的作用)。
下面舉例乙個穿衣服的裝飾模式例子:
場景:衣服有很多種,t恤,褲子,西裝,運動鞋,皮鞋,領帶等,至於怎麼組合無需關心,交給客戶決定。
分析:衣服要有人來穿,所以人是乙個具體的component,上述的各種衣服最終還是乙個衣服,所以乙個衣服的積累,作為抽象的裝飾存在,另外各種衣服就是乙個個具體的裝飾物件。
人(person具體的component):
class衣服(服飾的基類):person
//當前人
private
string
name;
public person(string
name)
//////
展示衣服
/// public
virtual
void
show()
", name));}}
///其他具體的服飾類:///衣服類
/// class
finery:person
public
override
void
show()}}
///呼叫:///t恤
/// class
tshirt:finery
}//////
褲子
/// class
trouser:finery
}//////
運動鞋
/// class
sportshoes:finery
}//////
西裝
/// class
suit:finery
}//////
皮鞋
/// class
eathershoes:finery
}//////
領帶
/// class
tie:finery
}
console.writeline("**中一共展示了兩種不同的裝扮,除了例項化的衣服不同之外,其餘過程均相同。例項化乙個person類,即例項化乙個具體的component,然後開始例項化各種各樣的衣服,然後通過decorate方法進行裝飾,最後呼叫show進行衣服的展示,效果如下:第一種打扮:");
person person = new person("
blue");
tshirt shirt = new
tshirt();
trouser trouser = new
trouser();
sportshoes sportshoes = new
sportshoes();
//開始裝飾了
shirt.decorate(person);
trouser.decorate(shirt);
sportshoes.decorate(trouser);
//開始展示衣服了
sportshoes.show();
console.writeline();
console.writeline(
"第二種打扮:");
suit suit = new
suit();
eathershoes eathershoes = new
eathershoes();
tie tie = new
tie();
//再次裝飾了
suit.decorate(person);
eathershoes.decorate(suit);
tie.decorate(eathershoes);
//開始展示衣服了
tie.show();
現在如果想增加一種衣服怎麼做呢,很簡單,增加乙個衣服類,繼承自finery類,重寫show方法即可。如果要換裝扮,也很簡單,只需定義需要的衣服型別,並且進行裝飾即可完成,**是不是非常的低耦合呢。
後記總結:
裝飾模式是為已有功能動態地新增更多功能的一種方式。當系統需要新功能時,裝飾模式提供了乙個很好的方案,它把每個要裝飾的功能放在了單獨的類中,並讓這個類包裝它所需要的物件,因此當需要執行特殊行為時,客戶**就可以在執行時有選擇地使用裝飾功能包裝物件。
優點:把類的核心職責和裝飾功能區分開了,而且去除相關類中重複的裝飾邏輯。
設計模式之裝飾設計模式
1.目的 動態擴充套件類的行為 開閉原則 對擴充套件開放,對修改關閉 2.要點 裝飾類和被裝飾類都實現同乙個介面或者繼承同乙個類 3.具體實現 被裝飾元件介面 被裝飾元件實現類實現 抽象類構建被裝飾元件實現被裝飾元件介面 裝飾類繼承抽象類 裝飾類 重寫抽象類方法 裝飾 4.例項 被裝飾類介面 pub...
設計模式之裝飾模式
有時如果需要對某乙個類增加乙個功能,可以使用繼承來實現。但是如果想要只是對某乙個物件來增加一項功能,則可能會用到裝飾模式。裝飾模式的主要作用是動態的給某乙個物件新增某些功能。如果此時使用繼承來新增功能時,會產生大量的子類,導致難以維護。裝飾模式的簡要類圖如下 其中 component為待增加功能 即...
設計模式之裝飾模式
template pattern 即模板模式 核心思想 產品不變的部分首先實現,將易變的部分抽象出來供子類完成。例如 一雙運動鞋大體製作流程各廠家基本一致,但是各環節實現細節可有些不一樣,不一樣的部分抽象出來讓不同廠家實現。即先有個框架,細節交給不同廠家實現 程式設計例項 趙本山小品中提到的將大象裝...