一、应用场景举例
需要设计圆、矩形两种形状,同时设计这两种形状的红色、蓝色版本,按照传统的思路,使用继承的方式,则如下图:
按这种方式,当需要的形状和颜色种类增多时,所定义的类的数量将会急剧增多,而且类之间会有很多重复的代码。如果运用装饰模式的思想,依照“组合优先于继承”原则,将“颜色”单独定义为一个“装饰类”,该类也继承自抽象基类,且拥有一个抽象基类的指针,用于操作传入的不同的形状对象。这样,在定义装饰类对象时,传入不同的形状对象,就可以实现基本形状——圆、矩形和装饰——红色、蓝色的任意组合了,如下图:
二、实例代码
#include <iostream>
using namespace std;
class Shape //定义抽象基类——形状
{
public:
virtual void draw()=0;
virtual ~Shape(){};
};
class Circle:public Shape //定义形状的子类——圆
{
public:
virtual void draw(){
cout<<"draw a circle"<<endl;
}
};
class Rectangle:public Shape//定义形状的子类——矩形
{
public:
virtual void draw(){
cout<<"draw a rectangle"<<endl;
}
};
class ShapeDecorator:public Shape //定义装饰类,表示对图形的装饰
{
public:
Shape * shape;
ShapeDecorator(Shape *s){
shape = s;
}
};
class RedShape:public ShapeDecorator //继承装饰类,定义装饰——红色
{
public:
RedShape(Shape *s):ShapeDecorator(s){}
virtual void draw(){
cout<<"Set red pen"<<endl; //进行装饰操作
shape->draw(); //操作传入的形状对象
}
};
class BlueShape:public ShapeDecorator//继承装饰类,定义装饰——蓝色
{
public:
BlueShape(Shape* s):ShapeDecorator(s){}
virtual void draw(){
cout<<"Set blue pen"<<endl; //进行装饰操作
shape->draw();//操作传入的形状对象
}
};
int main()
{
Shape *circle = new Circle(); //生成圆对象
Shape *rectangle = new Rectangle();//生成矩形对象
Shape *redCircle = new RedShape(circle);//生成红色圆
Shape *blueCircle = new BlueShape(circle);//生成蓝色圆
Shape *redRectangle = new RedShape(rectangle);//生成红色矩形
Shape *blueRectabgle = new BlueShape(rectangle);//生成蓝色矩形
//画出所有图形
circle->draw();
rectangle->draw();
redCircle->draw();
redRectangle->draw();
blueCircle->draw();
blueRectabgle->draw();
return 0;
}
运行结果: