装饰模式(Decorator)C++实现
动态的给一个对象额外添加一些额外职责。参与者:
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()(同样由多态决定),然后返回去执行之前没有执行结束的语句。