本文是學習劉偉技術部落格和《設計模式-可複用面向對象軟體的基礎》筆記,部落格連結:http://blog.csdn.net/lovelion/article/details/17517213
主要是對部落格和書本做提煉和記錄,更多是對設計模式的基礎架構學習,細節将略去,側重對每個設計模式架構的了解。
我應該了解和掌握的:
1)能夠畫出這個設計模式的架構框圖;
2)能夠根據架構框圖寫出對應的僞代碼;
3)這個模式的應用場景,主要優缺點。
1.裝飾模式
裝飾模式在不改變對象本身功能的基礎上添加額外的功能,比如給照片添加一個相框。同時他也是一種替代繼承的技術,使用關聯取代繼承;在裝飾模式中引入裝飾類,在裝飾類中既可以調用待裝飾的原有類方法,還可以新增方法,以擴充原有功能。
(1)定義
裝飾模式:動态的給一個對象添加一些額外的職責。就新增功能來說,Decorator模式相比生成子類更為靈活。
1) 裝飾模式結構圖
2)參與者
a) Component(抽象構件):定義一個對象業務方法,是具體建構和抽象裝飾類的共同父類,用戶端針對它程式設計。
b) ConcreteComponent(具體構件):定義具體構件,實作父類業務方法,裝飾類将會給這個對象增加額外的職責。
c) Decorator(抽象裝飾類):抽象構件子類,用于關聯一個抽象構件的指針,并定義一個與Component一緻的接口,直接調用裝飾之前對象的業務方法。
d) ConcreteDecorator(具體裝飾類):向具體構件增加額外的職責,不同的具體裝飾類增加不同的職責。調用抽象裝飾類的operation方法,同時增加新的業務方法,這邊是裝飾額外的功能。
3) 看圖寫代碼
/*
** FileName : DecoratorPattern
** Author : lin005
** Date : 2015/01/27
** Description : More information, please go to http://blog.csdn.net/amd123456789
*/
class Component
{
public:
virtual void operation() = 0;
};
//具體建構類
class ConcreteComponent:public Component
{
public:
void operation()
{
cout<<"ConcreteComponent"<<endl;
}
};
//抽象裝飾類
class Decorator:public Component
{
public:
//注入抽象類,保持一個對component的引用
Decorator(Component* c)
{
_component = c;
}
virtual void operation()//直接調用component的方法
{
_component->operation();
}
~Decorator()
{
if(_component != NULL)
{
delete _component;
_component = NULL;
}
}
protected:
//關聯一個component
Component* _component;
};
//具體狀态裝飾類
class ComcreteDecoratorA:public Decorator
{
public:
//注入一個component對象
ComcreteDecoratorA(Component* c):Decorator(c){}
//對客戶透明,始終還是調用operation()
virtual void operation()
{
//增加state狀态
addstate();
Decorator::operation();
}
//裝飾類要添加的職能
void addstate()
{
cout<<"要裝飾的狀态方法"<<endl;
}
};
//具體行為裝飾類
class ComcreteDecoratorB:public Decorator
{
public:
//注入一個component對象
ComcreteDecoratorB(Component* c):Decorator(c){}
virtual void operation()
{
//裝飾行為職能
addbehavior();
Decorator::operation();
}
void addbehavior()
{
cout<<"要裝飾的行為方法"<<endl;
}
};
//用戶端測試
int main(int argc, const char * argv[]) {
//用戶端針對抽象程式設計
Component *c;
Component* dA;
Component* dB;
Component* dAB;
c = new ConcreteComponent();//具體構件對象,即要裝飾前的對象
dA = new ComcreteDecoratorA(c);//具體裝飾對象A
dB = new ComcreteDecoratorB(c);//具體裝飾對象B
dAB = new ComcreteDecoratorA(dB);//同時裝飾A和B,非常友善,直接嵌套
c->operation();
dA->operation();
dB->operation();
dAB->operation();
return 0;
}
(2)總結
1)優點:
a) 對于擴充一個對象的功能,裝飾模式比靜态繼承更靈活,也很容易重複添加一個特性,不會導緻類的個數急劇增加。
b) 可以對一個對象進行多次裝飾,通過使用不同的具體裝飾類以及這些裝飾類的排列組合,得到功能更為強大的對象。
c) 符合開閉,具體構件類和具體裝飾類可以獨立變化,按需增加新的具體構件類和具體裝飾類。
2)缺點
a) 會産生許多小對象;這些對象僅僅在他們互相連接配接的方式上有所不同,而不是他們的類或是他們的屬性值有所不同。
b) 對于了解這些系統的人來說,很容易對他們進行定制,但是很難學習這些系統,排錯也困難。
3) 注意事項
a) 接口一緻性。裝飾對象的接口必須與他所裝飾的component的接口是一緻的。
b) 保持Component類的簡單性。它應集中于定義接口而不是存儲資料,對于資料的表示應延遲到子類,否則Component會變得過于複雜的龐大,難以大量使用。我們應該通過裝飾類對其進行擴充。
c) 可以省略抽象的Decorator類,當你僅需要添加一個職責時,沒必要定義抽象Decotator類。你常常需要處理現存的類層次結構而不是設計一個新的系統,這時可以把Decorator向Component轉發請求的職責合并到ComcreteDecorator中。
d) 如果隻有一個具體構件類,那麼抽象裝飾類可以作為該具體構件結構類的直接子類。如下圖:
(3)适用場景
1)在不影響其他對象的情況下,以動态、透明的方式給單個對象添加職責。
2)處理那些可以撤銷的職責,按需再進行添加。同時裝飾者模式的行為具有可疊加性。
3)當不能采用生成子類的方法進行擴充。一種是,可能有大量獨立的擴充,為支援每一種組合将産生大量的子類,使得子類數目呈爆炸性增長。另一種是可能因為類定義被隐藏,或類定義不能生成子類。