C++设计模式之装饰(Decorator)模式
2013-10-21 23:23
513 查看
理论不多讲,直接上例子吧:在一些赛车类游戏中,我们可以对自己的进行装饰(实际就是贴图),比如有一辆黑色的tubo911,我要将其进行喷漆弄成红色,过了一段时间,我又想将其喷成墨绿色,这样的功能怎样设计呢?可能我们第一想到的是用子类来拓展这样的功能,但是假如喷涂的顺序会对效果产生影响呢,就会发生子类爆炸的问题:黑色车涂红色、黑色车涂墨绿、黑色车先涂红色再涂墨绿、黑色车先涂墨绿再涂红色,每种效果都要创建一个子类。如果在增加一种车或增加一种喷涂颜色,子类的的数量将呈几何增长,显然这种设计方式不好。
针对这种问题,我们可以考虑,在对一辆车进行喷涂时,只考虑车当前的颜色和喷涂后的颜色,至于之前喷涂过几次、涂的什么颜色都由上一次喷涂操作进行管理。这样,喷涂操作就需要与喷涂后的车具有一样的一个操作,而且喷涂n次后的车需要与没有喷涂的车具有相同的待遇。考虑如下类层次:
![](http://img.blog.csdn.net/20131021230439218?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhhbmdsaWZ1MDgxMDIy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
我们让装饰操作与装饰对象具有相同的父类Car,Car可以派生出各种车:奥迪AudiCar、别克Buick等作为操作对象类。Car还派生出一个对汽车进行装饰的父类CarBrush,该类有两个特性值得注意:1、与装饰对象具有相同的父类,有相同的一个操作Paint。2、CarBrush保存了一个Car*指针。CarBrush派生出执行装饰的类。这样,当装饰类接受到一个操作对象(可以是没有装饰过的AudiCar类对象,也可以是装饰过的车,因为他们都可以用一个Car*指针关联),先让其接受对象自己调用Paint操作,再执行自己定义的装饰操作。装饰接受对象调用Paint时,就会利用多态将该对象Paint出来。如果需要增加一种车,直接将其定义到与AudiCar相同的层次上,要增加一种装饰,则将其定义到RedCarBrush层次上。
示例代码如下:
decorator.h
测试:
结果
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
这个模式最值得注意的地方就是上面所写的两点。
针对这种问题,我们可以考虑,在对一辆车进行喷涂时,只考虑车当前的颜色和喷涂后的颜色,至于之前喷涂过几次、涂的什么颜色都由上一次喷涂操作进行管理。这样,喷涂操作就需要与喷涂后的车具有一样的一个操作,而且喷涂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
这个模式最值得注意的地方就是上面所写的两点。
相关文章推荐
- C++设计模式之九:Decorator(装饰)
- C++设计模式8--装饰模式(Decorator)--动态的增减功能
- C++设计模式<六>:Decorator装饰模式
- c++ 设计模式6 (Decorator 装饰模式)
- 设计模式c++实现(一):装饰(Decorator)模式
- 23种设计模式之装饰器模式(结构型,2 Decorator,c++实现)
- C++设计模式之十四--Decorator装饰模式
- 设计模式C++描述----10.装饰(Decorator)模式
- c++设计模式----Decorator(装饰)
- c++ 设计模式6 (Decorator 装饰模式)
- C++设计模式之装饰模式(Decorator)
- 设计模式C++描述----10.装饰(Decorator)模式
- java 设计模式学习笔记九 decorator装饰模式
- [GoF设计模式]Decorator模式和Observer模式的C++实现
- .NET设计模式(10):装饰模式(Decorator Pattern)
- Java设计模式(7)装饰模式(Decorator模式)
- 面向对象设计模式之Decorator装饰模式(结构型)
- 设计模式学习-Decorator(装饰)
- 23设计模式之装饰模式(Decorator)
- 深入浅出设计模式(九):12.装饰模式(Decorator) 13.桥模式(Bridge)14.策略模式(Strategy)