(转)关于装饰者模式的思考
转自:http://du-hj.spaces.live.com/blog/cns!1E68466E595E5F05!125.entry
2006年3月
关于装饰者(Decorator)模式的思考
/*原创 By Blue Light*/
/*引用:设计模式可复用面向对象软件的基础*/
/*结构型模式*/。
1. 意图
Decorator:动态的给对象添加额外的职责。这比生成子类更灵活。
2. 别名
包装器Wr a p p e r
3. 动机
有时我们希望给某个对象而不是整个类添加一些功能。例如,一个图形用户界面工具箱
允许你对任意一个用户界面组件添加一些特性,例如边框,或是一些行为,例如窗口滚动。
包装器Wr a p p e r
3. 动机
有时我们希望给某个对象而不是整个类添加一些功能。例如,一个图形用户界面工具箱
允许你对任意一个用户界面组件添加一些特性,例如边框,或是一些行为,例如窗口滚动。
4. 适用性
以下情况使用D e c o r a t o r模式
• 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
• 处理那些可以撤消的职责。
• 当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持
每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类
定义被隐藏,或类定义不能用于生成子类。
以下情况使用D e c o r a t o r模式
• 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
• 处理那些可以撤消的职责。
• 当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持
每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类
定义被隐藏,或类定义不能用于生成子类。
5.代码示例
#include <iostream>
using namespace std;
using namespace std;
class Component //被装饰者和装饰者的接口
{
public:
virtual void Draw() = 0;
};
{
public:
virtual void Draw() = 0;
};
class Decorator : public Component //装饰者
{
public:
Decorator(Component *c) : _component(c){}
~Decorator()
{
delete _component;
}
virtual void Draw()
{
_component->Draw();
}
private:
Component *_component;
};
{
public:
Decorator(Component *c) : _component(c){}
~Decorator()
{
delete _component;
}
virtual void Draw()
{
_component->Draw();
}
private:
Component *_component;
};
class MyComponent : public Component //被装饰者
{
public:
virtual void Draw()
{
cout << "MyComponent::Draw()" << endl;
}
};
{
public:
virtual void Draw()
{
cout << "MyComponent::Draw()" << endl;
}
};
class BorderDecorator : public Decorator //边框装饰
{
public:
BorderDecorator(Component *c) : Decorator(c){}
virtual void Draw()
{
cout << "DrawBorder..." << endl;
Decorator::Draw();
}
};
class ScrollDecorator : public Decorator //滚动条装饰
{
public:
ScrollDecorator(Component *c) : Decorator(c){}
virtual void Draw()
{
cout << "DrawSrollbar..." << endl;
Decorator::Draw();
}
};
{
public:
ScrollDecorator(Component *c) : Decorator(c){}
virtual void Draw()
{
cout << "DrawSrollbar..." << endl;
Decorator::Draw();
}
};
int main()
{
Component *c1 = new MyComponent(); //未加装饰的组件
c1->Draw();
delete c1;
{
Component *c1 = new MyComponent(); //未加装饰的组件
c1->Draw();
delete c1;
Component *c2 = new BorderDecorator(
new MyComponent()); //装饰边框的组件
c2->Draw();
delete c2;
new MyComponent()); //装饰边框的组件
c2->Draw();
delete c2;
Component *c3 = new ScrollDecorator(
new BorderDecorator(
new MyComponent())); //同时装饰上边框和滚动条的组件
c2->Draw();
delete c3;
new BorderDecorator(
new MyComponent())); //同时装饰上边框和滚动条的组件
c2->Draw();
delete c3;
return 0;
}
}
6.一些思考:
根据我学泛型编程的经验,我想可以用模板的方法实现Decorator模式,虽然不如以上方法灵活,比如不能在运行时动态添加删除职责,但它避免了虚调用的运行时开销,我想在某些场合下会有用的。
class MyCompoent //我的组件,被装饰者
{
public:
void Draw()
{
cout << "MyComponent::Draw()" << endl;
}
};
{
public:
void Draw()
{
cout << "MyComponent::Draw()" << endl;
}
};
template <typename T1,typename T2> //增加装饰
class Decorator2 : public T1,public T2
{
public:
void Draw()
{
T1::Draw();
T2::Draw();
}
};
class Decorator2 : public T1,public T2
{
public:
void Draw()
{
T1::Draw();
T2::Draw();
}
};
class BorderDecorator //边框装饰
{
public:
void Draw()
{
cout << "DrawBorder..." << endl;
}
};
{
public:
void Draw()
{
cout << "DrawBorder..." << endl;
}
};
class ScrollDecorator //滚动条装饰
{
public:
void Draw()
{
cout << "DrawSrollbar..." << endl;
}
};
{
public:
void Draw()
{
cout << "DrawSrollbar..." << endl;
}
};
int main()
{
//未加装饰的组件
MyCompoent c1;
c1.Draw();
{
//未加装饰的组件
MyCompoent c1;
c1.Draw();
//装饰边框的组件
Decorator2< BorderDecorator, MyCompoent > c2;
c2.Draw();
Decorator2< BorderDecorator, MyCompoent > c2;
c2.Draw();
//同时装饰上边框和滚动条的组件
Decorator2< ScrollDecorator, Decorator2 < BorderDecorator,MyCompoent> > c3;
c3.Draw();
Decorator2< ScrollDecorator, Decorator2 < BorderDecorator,MyCompoent> > c3;
c3.Draw();
return 0;
}
}

浙公网安备 33010602011771号