九、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 ) );
个人理解:
装饰模式的结构可以理解为一个只有一个组件的组合模式。装饰类与待装饰类共同拥有一个抽象父类。注意装饰类的构造函数和其私有成员变量,巧妙的运用来达成动态装饰的目的(例子中具体描述了这一技巧)。另外,每个装饰的操作在完成自己定义的装饰外,一定要转发操作来考虑到其他的装饰(见例子)。