Decorator装饰模式
作用:动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。
UML图如下:
Component是定义一个对象接口,可以给这些对象动态地添加职责。
ConcreteComponent是定义了一个具体的对象,也可以给这个对象添加一些职责。
Decorator,装饰抽象类,继承了Component,从外类来扩展Component类的功能,但对于Component来说,是无需知道Decorator的存在的。
至于ConcreteDecorator就是具体的装饰对象,起到给Component添加职责的功能。
要善于变通,如果只有一个ConcreteComponent类而没有抽象的Component类,那么Decorator类可以是ConcreteComponent的一个子类。
同样道理,如果只有一个ConcreteDecorator类,那么就没有必要建立一个单独的Decorator类,而可以把Decorator和ConcreteDecorator的责任合并成一个类。
新加入的东西仅仅是为了满足一些只在某种特定情况下才会执行的特殊行为 的需要。而装饰模式却提供了一个非常好的解决方案,它把每个要装饰的功能放在单独的类中,并让这个类包装它所要装饰的对象,因此,当需要执行特殊行为 时,客户代码就可以在运行时根据需要有选择地、按顺序地使用装饰功能包装对象了。
代码如下:
Decorator.h
#ifndef _DECORATOR_H_
#define _DECORATOR_H_
//Component抽象类,定义该类对象的接口
class Component
{
public:
virtual ~Component();
virtual void Operation()=0;
protected:
Component();
};
//ConcreteDecorator:具体的Component对象,可以给该对象动态 添加职责
class ConcreteComponent:public Component
{
public:
ConcreteComponent();
~ConcreteComponent();
virtual void Operation();
};
//Decorator:装饰抽象类,继承自Component
class Decorator:public Component
{
public:
Decorator(Component* com);
void SetComponent(Component* com);
virtual ~Decorator();
virtual void Operation();
protected:
Component* _com;
};
//ConcreteDecorator就是具体的装饰对象之一,起到给Component添加职责的功能
class ConcreteDecoratorA:public Decorator
{
public:
ConcreteDecoratorA(Component* com);
~ConcreteDecoratorA();
virtual void Operation();
void AddBehavorA();
};
//ConcreteDecorator就是具体的装饰对象之二,起到给Component添加职责的功能
class ConcreteDecoratorB:public Decorator
{
public:
ConcreteDecoratorB(Component* com);
~ConcreteDecoratorB();
virtual void Operation();
void AddBehavorB();
};
//ConcreteDecorator就是具体的装饰对象之三,起到给Component添加职责的功能
class ConcreteDecoratorC:public Decorator
{
public:
ConcreteDecoratorC(Component* com);
~ConcreteDecoratorC();
virtual void Operation();
void AddBehavorC();
};
//ConcreteDecorator就是具体的装饰对象之四,起到给Component添加职责的功能
class ConcreteDecoratorD:public Decorator
{
public:
ConcreteDecoratorD(Component* com);
~ConcreteDecoratorD();
virtual void Operation();
void AddBehavorD();
};
//只添加一种装饰,则不用抽象出装饰基类
class DecoratorOnlyOne:public Component
{
public:
DecoratorOnlyOne(Component* com);
~DecoratorOnlyOne();
virtual void Operation();
void AddBehavor();
private:
Component* _com;
};
//如果只有一个ConcreteComponent类而没有抽象的Component类,那么Decorator类可以是ConcreteComponent的一个子类。
//略
#endif
Decorator.cpp
#include "Decorator.h"
#include <iostream>
using namespace std;
Component::Component()
{}
Component::~Component()
{
cout << "~Component" << endl;
}
ConcreteComponent::ConcreteComponent()
{}
ConcreteComponent::~ConcreteComponent()
{
cout << "~ConcreteComponent" << endl;
}
void ConcreteComponent::Operation()
{
cout << "原职责:ConcreteComponent::Operation" << endl;
}
Decorator::Decorator(Component* com)
{
this->_com = com;
}
void Decorator::SetComponent(Component* com)
{
this->_com = com;
}
Decorator::~Decorator()
{
cout << "~Decorator" << endl;
delete this->_com;
this->_com = NULL;
}
void Decorator::Operation()
{}
ConcreteDecoratorA::ConcreteDecoratorA(Component* com):Decorator(com)
{}
ConcreteDecoratorA::~ConcreteDecoratorA()
{
cout << "~ConcreteDecoratorA" << endl;
}
void ConcreteDecoratorA::Operation()
{
this->_com->Operation();
//附加职责A
this->AddBehavorA();
}
void ConcreteDecoratorA::AddBehavorA()
{
cout << "附加职责A:ConcreteDecoratorA::AddBehavorA" << endl;
}
ConcreteDecoratorB::ConcreteDecoratorB(Component* com):Decorator(com)
{}
ConcreteDecoratorB::~ConcreteDecoratorB()
{
cout << "~ConcreteDecoratorB" << endl;
}
void ConcreteDecoratorB::Operation()
{
this->_com->Operation();
//附加职责B
this->AddBehavorB();
}
void ConcreteDecoratorB::AddBehavorB()
{
cout << "附加职责B:ConcreteDecoratorB::AddBehavorB" << endl;
}
ConcreteDecoratorC::ConcreteDecoratorC(Component* com):Decorator(com)
{}
ConcreteDecoratorC::~ConcreteDecoratorC()
{
cout << "~ConcreteDecoratorC" << endl;
}
void ConcreteDecoratorC::Operation()
{
this->_com->Operation();
//附加职责C
this->AddBehavorC();
}
void ConcreteDecoratorC::AddBehavorC()
{
cout << "附加职责C:ConcreteDecoratorC::AddBehavorC" << endl;
}
ConcreteDecoratorD::ConcreteDecoratorD(Component* com):Decorator(com)
{}
ConcreteDecoratorD::~ConcreteDecoratorD()
{
cout << "~ConcreteDecoratorD" << endl;
}
void ConcreteDecoratorD::Operation()
{
this->_com->Operation();
//附加职责D
this->AddBehavorD();
}
void ConcreteDecoratorD::AddBehavorD()
{
cout << "附加职责D:ConcreteDecoratorD::AddBehavorD" << endl;
}
//**************只添加一种修饰******************
DecoratorOnlyOne::DecoratorOnlyOne(Component* com):_com(com)
{
}
DecoratorOnlyOne::~DecoratorOnlyOne()
{
cout << "~DecoratorOnlyOne" << endl;
delete this->_com;
this->_com = NULL;
}
void DecoratorOnlyOne::Operation()
{
this->_com->Operation();
this->AddBehavor();
}
void DecoratorOnlyOne::AddBehavor()
{
cout << "附加唯一职责:DecoratorOnlyOne::AddBehavor" << endl;
}
main.cpp
#include "Decorator.h"
#include <iostream>
using namespace std;
int main()
{
Component* pCom = new ConcreteComponent(); //要装饰的对象
Decorator* pDec = NULL;
pDec = new ConcreteDecoratorA(pCom); //给装饰对象附加职责A
pDec = new ConcreteDecoratorB(pDec); //给装饰对象附加职责B
pDec = new ConcreteDecoratorC(pDec); //给装饰对象附加职责C
pDec = new ConcreteDecoratorD(pDec); //给装饰对象附加职责D
pDec->Operation();
cout << "-------------------------------" << endl;
//只添加一种修饰
Component* pCom1 = new ConcreteComponent();
DecoratorOnlyOne* pDec1 = new DecoratorOnlyOne(pCom1);
pDec1->Operation();
cout << "-------------------------------" << endl;
delete pDec;
cout << "-------------------------------" << endl;
delete pDec1;
return 0;
}
运行结果:
Decorator模式除了采用组合的方式取得了比采用继承方式更好的效果,Decorator模式还给设计带来一种“即用即付”的方式来添加职责。在OO设计和分析经常有这样一种情况:为了多态,通过父类指针指向其具体子类,但是这就带来另外一个问题,当具体子类要添加新的职责,就必须向其父类添加一个这个职责的抽象接口,否则是通过父类指针是调用不到这个方法了。这样处于高层的父类就承载了太多的特征(方法),并且继承自这个父类的所有子类都不可避免继承了父类的这些接口,但是可能这并不是这个具体子类所需要的。而在Decorator模式提供了一种较好的解决方法,当需要添加一个操作的时候就可以通过Decorator模式来解决,你可以一步步添加新的职责。