動態給一個對象額外添加一些額外職責。參與者:
Component:定義對象介面,可以給這些對象動態添加職責。
ConcreteComponent:定義一個對象,可以給這個對象添加職責。
Decorator:維持一個指向Component對象的指標,並定義一個與Component介面一致的介面。
ConcreteDecorator(BorderDecorator和ScrollDecorator):向組件添加職責。
Decorator將請求轉寄給他的Component對象,並有可能在轉寄請求之後執行一些附加的動作。
#include<iostream>#include<string>using namespace std;class Component{public: Component(){}; virtual void Draw()=0;};class ConcreteComponent:public Component{public: ConcreteComponent(const string str):m_name(str){} void Draw() { cout<<"draw a "<<m_name<<" component"<<endl; }private: string m_name;};//這個類其實就是封裝了一個指標Component指標,因為需要用到Component的多態性class Descorator:public Component{public: Descorator(Component *_component) { this->_component = _component; } virtual ~Descorator(){delete _component;} void Draw() { _component->Draw(); }private: Component *_component;}; class BorderDecorator:public Descorator{public: BorderDecorator(Component *_component,int_width):Descorator(_component) { this->_width = _width; } void Draw() { Descorator::Draw(); DrawBorder(); }private: void DrawBorder() { cout<<"add "<<_width<<" border "<<endl; }private: int _width;};class ScrollDecorator:public Descorator{public: ScrollDecorator(Component* _component,int _depth):Descorator(_component) { this->_depth = _depth; } void Draw() { Descorator::Draw(); DrawScroll(); }private: void DrawScroll() { cout<<"add "<<_depth<<" scrollBar "<<endl; }private: int _depth;};int main(){ Component *ptr = new BorderDecorator( new ScrollDecorator( new ConcreteComponent("lsj"),12),32);//C ptr->Draw();//D system("pause"); return 0;}
運行結果:
我覺得://D:執行過程中應該是這樣的:
(1)首先通過ptr->draw(),執行Component調用draw(),由於多態性執行BorderDecorator::Draw()。
(2)然後BorderDecorator::Draw()中第一句話Descorator::Draw()。
(3)Descorator::Draw()中又執行_component->draw(),而此時_component此時為new ScrollrDecorator()後的的指標(可以從C行的建構函式得出,因為構造的時候採用new ScrollDecorator),於是執行ScrollDecorator::Draw()
(轉到這個地方執行是由多態決定的)。
(4)ScrollDecorator::Draw()又執行Descorator::Draw(),而Descorator::Draw()執行_component->draw(),此時_component指標的值為newConcreteComponent(從C行的建構函式可以看出),於是執行ConcreteComponent::draw()(同樣由多態決定),然後返回去執行之前沒有執行結束的語句。