九、Decorator(装饰)
情景举例:
动态地给一个对象添加一些额外的职责。
代码示例:
/* 装饰与待装饰类共同的抽象类
*/
class VisualComponent {
public:
VisualComponent();
virtual void Draw();
virtual void Resize();
// ...
};
/* 装饰的抽象类。注意成员变量_component,
* 它指向的是下一层装饰或者待装饰类
*/
class Decorator : public VisualComponent {
public:
Decorator(VisualComponent*);
/*
*/
virtual void Draw();
virtual void Resize();
// ...
private:
VisualComponent* _component;
};
/* 将请求转发给下一层装饰或者待装饰类
*/
void Decorator::Draw () {
_component->Draw();
}
void Decorator::Resize () {
_component->Resize();
}
/*
*/
class BorderDecorator : public Decorator {
public:
BorderDecorator(VisualComponent*, int borderWidth);
virtual void Draw();
private:
void DrawBorder(int);
private:
int _width;
};
/* 注意,执行装饰时,一定要考虑到其他的装饰操作
* 由Decorator::Draw();转发
*/
void BorderDecorator::Draw () {
Decorator::Draw();
DrawBorder(_width);
}
/* 这里注意下装饰类和其子类的构造函数
*/
class ScrollDecorator : public Decorator {
public:
ScrollDecorator(VisualComponent*);
};
/*
*/
class TextView : public VisualComponent {
};
/* 测试用类,与结构无关
*/
class Window {
public:
void SetContents (VisualComponent* contents);
};
void Window::SetContents (VisualComponent* contents) {
// ...
}
void dummy()
{
Window* window = new Window;
TextView* textView = new TextView;
/*
*/
window->SetContents(textView);
/* 注意装饰的用法
*/
window->SetContents(
new BorderDecorator(
new ScrollDecorator(textView), 1
)
);
个人理解:
装饰模式的结构可以理解为一个只有一个组件的组合模式。装饰类与待装饰类共同拥有一个抽象父类。注意装饰类的构造函数和其私有成员变量,巧妙的运用来达成动态装饰的目的(例子中具体描述了这一技巧)。另外,每个装饰的操作在完成自己定义的装饰外,一定要转发操作来考虑到其他的装饰(见例子)。