裝飾器模式(Decorator Pattern):允許向一個現有的對象添加新的功能,同時又不改變其結構。這種類型的設計模式屬於結構型模式,它是作為現有的類的一個包裝。這種模式創建了一個裝飾類,用來包裝原有的類,並在保持類方法簽名完整性的前提下,提供了額外的功能。
裝飾者模式適用場景:
(1)以動態的方式給對象添加職責。
(2)處理那些可以撤銷的職責。
(3)當采用生成子類的方法進行擴充時,可能有大量獨立的擴展,為支持每一種組合將產生大量的子類,使得子類數目呈爆炸性增長。
(1)抽象組件(Component):給出一個抽象接口,以規范准備接受附加責任的對象。
(2)被裝飾者(ConcreteComponent):Component的具體實現,也就是我們要裝飾的具體對象。
(3)裝飾者組件(Decorator):持有組件對象的實例引用,該類的職責就是為了裝飾具體組件對象,定義的基類。
(4)具體裝飾(ConcreteDecorator):負責給構件對象裝飾附加的功能。
裝飾者模式實現步驟:
1.增強類與被增強類實現同一接口
2.增強類里面得到被增強類的引用(只要在增強類里面傳入被增強類對象的一定就是裝飾者模式)
3.對於不需要改寫的方法,調用被增強類原有方法,對應需要改寫增強的方法寫自己的邏輯
下面就以一杯奶茶說起,我最喜歡喝大杯阿水茶的珍珠奶茶,可是有時候也會不滿足奶茶只有珍珠,在天氣熱的時候我還要加冰塊,心情好的時候再加個椰果等,這些其實都是對奶茶的拓展即裝飾。
我們先來創建一個奶茶的抽象類,相當於Component
class Milk_Tea
{
public:
virtual void request(){};
};
再寫一個珍珠奶茶類,相當於被裝飾者
class Milk_Tea
{
public:
virtual void request(){};
};
然后實現裝飾類:
class Decorator:public Milk_Tea {
protected:
Milk_Tea *milkyTea;
public:
Decorator(Milk_Tea *a){
milkyTea=a;
}
virtual void request(){
milkyTea->request();
}
};
分別寫出不同裝飾具體類:
class Add1:public Decorator {
public:
Add1(Milk_Tea *a):Decorator(a){
}
void request() {
milkyTea->request();
add_ice();
}
void add_ice(){
cout<<"天好熱啊,老板我想加個冰。。。"<<endl;
}
};
class Add2:public Decorator {
public:
Add2(Milk_Tea *a):Decorator(a){
}
void request(){
milkyTea->request();
add_fruit();
}
void add_fruit(){
cout<<"再加個椰果,謝謝。。。"<<endl;
}
};
客戶端:
int main()
{
Milk_Tea *m1=new Bubble_Tea();
Decorator *m2=new Add1(m1);
Decorator *m3=new Add2(m2);
m3->request();
return 0;
}
效果:
優點:
1、目的在於擴展對象的功能。裝飾者模式提供比繼承更好的靈活性。裝飾是動態的,運行時可以修改的;繼承是靜態的,編譯期便已確定好。
2、通過使用不同的裝飾類及對他們的排列組合,可以創造出許多不同行為的組合。
缺點:
1、 產生很多的小對象,大量的小對象會占用內存。
2、 組合方式很多,很容易出錯。