您的位置:首页 > 编程语言 > C语言/C++

C++设计模式之装饰(Decorator)模式

2013-10-21 23:23 513 查看
理论不多讲,直接上例子吧:在一些赛车类游戏中,我们可以对自己的进行装饰(实际就是贴图),比如有一辆黑色的tubo911,我要将其进行喷漆弄成红色,过了一段时间,我又想将其喷成墨绿色,这样的功能怎样设计呢?可能我们第一想到的是用子类来拓展这样的功能,但是假如喷涂的顺序会对效果产生影响呢,就会发生子类爆炸的问题:黑色车涂红色、黑色车涂墨绿、黑色车先涂红色再涂墨绿、黑色车先涂墨绿再涂红色,每种效果都要创建一个子类。如果在增加一种车或增加一种喷涂颜色,子类的的数量将呈几何增长,显然这种设计方式不好。

针对这种问题,我们可以考虑,在对一辆车进行喷涂时,只考虑车当前的颜色和喷涂后的颜色,至于之前喷涂过几次、涂的什么颜色都由上一次喷涂操作进行管理。这样,喷涂操作就需要与喷涂后的车具有一样的一个操作,而且喷涂n次后的车需要与没有喷涂的车具有相同的待遇。考虑如下类层次:



我们让装饰操作与装饰对象具有相同的父类Car,Car可以派生出各种车:奥迪AudiCar、别克Buick等作为操作对象类。Car还派生出一个对汽车进行装饰的父类CarBrush,该类有两个特性值得注意:1、与装饰对象具有相同的父类,有相同的一个操作Paint。2、CarBrush保存了一个Car*指针。CarBrush派生出执行装饰的类。这样,当装饰类接受到一个操作对象(可以是没有装饰过的AudiCar类对象,也可以是装饰过的车,因为他们都可以用一个Car*指针关联),先让其接受对象自己调用Paint操作,再执行自己定义的装饰操作。装饰接受对象调用Paint时,就会利用多态将该对象Paint出来。如果需要增加一种车,直接将其定义到与AudiCar相同的层次上,要增加一种装饰,则将其定义到RedCarBrush层次上。

示例代码如下:

decorator.h

#ifndef __Decorator_H_
#define __Decorator_H_

#include <iostream>

using namespace std;

class Car
{
public:
virtual void Paint() = 0;
};

class AudiCar : public Car
{
public:
void Paint() { cout<<"Audi Car Default Color is Black"<<endl; }
};

class BuickCar : public Car
{
public:
void Paint() { cout<<"Buick Car Default Color is Red"<<endl; }
};

class CarBrush : public Car
{
public:
CarBrush() : m_pCar(0) {}

void	SetCar(Car* pcar)	{ m_pCar = pcar; }
Car*	GetCar()			{ return m_pCar; }

protected:
Car* m_pCar;	//要操作的对象
};

class RedCarBrush : public CarBrush
{
public:
void Paint()
{
if(0 == m_pCar)
return;
m_pCar->Paint();
cout<<"Paint the car with red brush"<<endl;
}
};

class BlueCarBrush : public CarBrush
{
public:
void Paint()
{
if(0 == m_pCar)
return;
m_pCar->Paint();
cout<<"Paint the car with blue brush"<<endl;
}
};

#endif

测试:

int _tmain(int argc, _TCHAR* argv[])
{
AudiCar		audi;
BuickCar	buick;

RedCarBrush  redbrush;
BlueCarBrush bluebrush;

cout<<"Now DIY the audi car:"<<endl;
redbrush.SetCar(&audi);			//接收一辆没装饰过的奥迪车,喷红色
bluebrush.SetCar(&redbrush);		//接收到一辆喷过红色漆的车辆,喷蓝色
bluebrush.Paint();			//执行操作

cout<<endl<<"Now DIY the buick car:"<<endl;
bluebrush.SetCar(&buick);
redbrush.SetCar(&bluebrush);
redbrush.Paint();

return 0;
}


结果

Now DIY the audi car:

Audi Car Default Color is Black

Paint the car with red brush

Paint the car with blue brush

Now DIY the buick car:

Buick Car Default Color is Red

Paint the car with blue brush

Paint the car with red brush

这个模式最值得注意的地方就是上面所写的两点。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: