定义
动态的给一个对象添加一些辅助功能,而不改变原有的类。
案例
假如现在有个文本控件TextView,它可以在屏幕上显示文字,但当文字过多的时候,一个屏幕显示不下,这时就需要给它添加一个滚动条。给一个窗口加一个滚动条不是原有的功能,而是额外的功能,比如还可以加一个黑色外框,而且这些操作不是为某一个控件设定的,其他的控件也可以用,如果用子类化来实现,就得不偿失了。使用装饰模式可以轻松的实现:
Widget是一个窗口基类,它定义了所有窗口类需要的操作。TextView和Decorator继承相同的基类,因为它们必须体统统一的接口。
Class Widget {
public:
virtual void draw() { ... }
virtual void resize() { ... }
}
class TextView : public Widget {
public:
virtual void draw() { drawText(); }
private:
string m_text;
}
class Decorator : public Widget {
public:
Decorator(Widget* component) { component = component; }
virtual void draw() { m_component->draw(); }
virtual void resize() { m_component->resize(); }
private:
Widget* m_component;
}
class ScrollDecorator : public Decorator {
public:
ScrollDecorator(Widget* widget) : Decorator(widget) { ... }
virtual void draw( Decorator::draw(); drawScroll(); )
virtual void resize( resizeScroll(); )
}
class BorderDecorator : public Decorator {
public:
BorderDecorator(Widget* widget, int width);
virtual void draw() { Decorator::draw(); drawBorder(); }
private:
int m_width;
}
TextView* textView = new TextView();
ScrollDecorator* scrollDecroator = new ScrollDecorator(textView);
BorderDecorator* borderDecorator = new BorderDecorator(scrollDecorator);
适用性
- 在不影响其他对象的情况下,以动态、透明的方式给某个对象添加功能。
- 处理可以撤销的功能。
- 当不能使用子类的方式进行扩充时。
优缺点
- 比静态继承更灵活
- 避免在层次结构中的类有太多的特性
注意
装饰类Decorator和被装饰对象textView的类有相同的接口,拥共同的基类。
相关模式
Adapter模式是改变对象的接口的方式,提供给其他类使用。
Composite模式是在与对象的聚集,Decorator模式是Composite模式的一个退化,只在于添加一些额外功能。
Strategy模式是改变对象内核的方式进行,Decorator是改变对象的外表。