Decorator模式
在OO设计和开发过程中,若我们需要为一个已经定义好的类添加新的操作,通常会定义一个新类来继承
已定义好的类,这样会带来一个问题(见<动机>),通过继承还带来了系统的复杂性。
Decorator模式提供了一种给类添加操作的方法,不是通过继承实现,而是通过组合,使组件对客户透明。
一、意图:
动态地给一个对象添加一些额外的职责,就增加功能来说,Decorator更为灵活。
二、动机:
有时我们希望给某个对象而不是整个类添加一些功能。例如:一个图形工具箱允许你对任何一个用户界面组件
添加一些特性,像是边框,或是一些行为,如窗口滚动。使用继承可以被多个子类实例使用,但不够灵活,因为边框
的选择是静态的,用户不能控制对组件加边框的方式和时机。
三、C++示例:
//decorator.h
#ifndef DECORATOR_H
#define DECORATOR_H
class Component{
public:
virtual ~Component();
virtual void Operation();
protected:
Component();
};
class ConcreteComonent : public Component{
public:
ConcreteComonent();
~ConcreteComonent();
void Operation();
};
class Decorator : public Component{
public:
Decorator(Component* com);
virtual ~Decorator();
void Operation();
protected:
Component *m_com;
};
class ConcreteDecorator : public Decorator{
public:
ConcreteDecorator(Component* com);
~ConcreteDecorator();
void Operation();
void AddedBehavior();
};
#endif // DECORATOR_H
//decorator.cpp
#include "decorator.h"
#include <iostream>
Component::Component(){
}
Component::~Component(){
}
void Component::Operation(){
}
ConcreteComonent::ConcreteComonent(){
}
ConcreteComonent::~ConcreteComonent(){
}
void ConcreteComonent::Operation(){
std::cout << "ConcreteComponent operation..." << std::endl;
}
Decorator::Decorator(Component *com){
this->m_com = com;
}
Decorator::~Decorator(){
delete m_com;
}
void Decorator::Operation(){
}
ConcreteDecorator::ConcreteDecorator(Component *com)
: Decorator(com){
}
ConcreteDecorator::~ConcreteDecorator(){
}
void ConcreteDecorator::AddedBehavior(){
std::cout << "ConcreteDecorator::AddedBehavior..." << std::endl;
}
void ConcreteDecorator::Operation(){
m_com->Operation();
this->AddedBehavior();
}
//main.cpp
#include "decorator.h"
#include <iostream>
int main(int argc,char* argv[]){
Component* com = new ConcreteComonent();
Decorator* decorator = new ConcreteDecorator(com);
decorator->Operation();
delete decorator;
return 0;
}
四、讨论:
当具体子类要添加新的方法,就必须向其父类添加这个方法的抽象接口,否则通过父类指针是调用不到新方法的,
这样父类就承载了太多的方法,继承自此父类的子类不可避免的继承了父类的这些接口,但这可能并不是某些具体子类
所需要的,用Decorator模式可更好的解决,其实就是组合较继承的优势。
注意Decorator模式和Composite模式差异比较。
Decorator模式和Proxy模式都是使用组合为对象提供更多的操作。区别是:Proxy会为其他对象提供一个代理
以控制对这个对象的访问。