菜鸟教程连接https://www.runoob.com/design-pattern/decorator-pattern.html
UML类图入下 :
在Java的IO流的类图
解决的问题 :
- 想给一个类扩展功能,但是不想继承
- 可以动态扩展功能,撤消功能(不知到体现在哪里)
注意点:
- 装饰器需要继承自被装饰者
概括:
- 装饰器需要继承自被装饰者
- 装饰器有一个被装饰者成员变量,重写接口时可以调用该成员变量的函数
用到的地方:
- JDK的IO流
实现:
现在我们要做个画图工具,如上面的类图,目前我们已有一个Shape图形接口
,
两个具体图形类Rect和Circle
,现在我们想要添加一个画红色
图形的功能,但是又不想动那两个图形类(不想继承),于是可以添加一个装饰器类,该装饰器拥有图形的所有功能draw()
,并且还有扩展的功能setRedBorde()
可以画出红色图形,具体做法就是:装饰器实现图形接口,有一个图形成员变量shape
,通过构造函数设置shape
,实现的接口可以直接调用shape->draw()
,于是就可以在装饰器里添加新的功能setRedBorde()
了。
代码如下:
原来已经有的图形接口Shape
和两个具体实现类Rect
,Circle
// 原来已有的图形接口
class Shape : public MajiaoObject {
public :
Shape() { }
~Shape() { }
// 图形接口类的绘制方法
virtual void draw() { }
};
// 具体长方形类
class Rect : public Shape {
public :
int w, h;
Rect() { }
~Rect() { }
virtual void draw() { cout << "矩形绘制算法" << endl; }
};
// 具体圆形类
class Circle : public Shape {
public :
int r, d;
Circle() { }
~Circle() { }
virtual void draw() { cout << "Bresenham画圆算法" << endl; }
};
现在我们要扩展新功能画红色图形
,不想去挨个继承Rect
和Circle
,
于是有了装饰器类
// 装饰器接口,必须继承被装饰者的接口
class ShapeDecorator : public Shape {
public :
// 被装饰的对象
Shape* shape;
// 使用构造设置成员变量
ShapeDecorator(Shape* shape) { this->shape = shape; }
~ShapeDecorator() { }
};
// 实现一个具体的装饰器【红色绘制图形装饰器】
class RedShapeDecorator : public ShapeDecorator {
public :
// 调用父类的构造
RedShapeDecorator(Shape* shape) : ShapeDecorator(shape) { }
~RedShapeDecorator() { }
virtual void draw() {
// 调用被装饰者的draw
if (shape) {
setRedBorde(); // 设置画笔颜色
shape->draw();
}
}
// 给原来的图形类添加一个设置边框为红色的功能,但是不需要继承原来的类
virtual void setRedBorde() { cout << "画笔设置成红色了" << endl; }
};