装饰器模式(Decorator)
为对象动态的添加功能
装饰器模式
简要介绍
就是为了动态的给某个类添加功能
使用场景
不想增加子类的时候,想要扩展某个类的功能,就使用装饰器模式
比如说有一个长方形类,还有一个圆形类,都继承了一个形状接口,现在想给长方形和圆形执行 draw 方法的时候,不单纯是绘制形状,还要加一个红色边框的绘制
一般情况解决:长方形增加一个红色长方形子类,圆形再加一个红色圆形子类,重写 draw 方法
装饰器如何解决:装饰器抽象类实现形状接口,构造方法参数是形状接口,然后一个红色装饰器继承此抽象类,在红色装饰器类中绘制并添加红色边框功能
优点
装饰器和被装饰的类可以独立发展,不耦合,装饰器可以理解为继承的替代,动态扩展某个类功能
缺点
多层装饰会变的复杂
类图
![image-20220421204203971](/articles/edbb2e9c/C8AeF16652image-20220421204203971.png)
例子
情景描述
比如说有一个长方形类,还有一个圆形类,都继承了一个形状接口,现在想给长方形和圆形执行 draw 方法的时候,不单纯是绘制形状,还要加一个红色边框的绘制
具体实现
shape 形状接口:
package icu.sunnyc;
/**
* @author :hc
* @date :Created in 2022/4/6 21:46
* @modified :
*/
public interface Shape {
/**
* 画图形
*/
void draw();
}
长方形类:
package icu.sunnyc;
/**
* @author :hc
* @date :Created in 2022/4/6 21:47
* @modified :
*/
public class Rectangle implements Shape {
/**
* 画长方形
*/
@Override
public void draw() {
System.out.println("画一个长方形");
}
}
圆形类:
package icu.sunnyc;
/**
* @author :hc
* @date :Created in 2022/4/6 21:48
* @modified :
*/
public class Circle implements Shape {
/**
* 画圆
*/
@Override
public void draw() {
System.out.println("画圆");
}
}
装饰器登场:
package icu.sunnyc;
/**
* @author :hc
* @date :Created in 2022/4/6 21:49
* @modified :
*/
public abstract class ShapeDecorator implements Shape {
protected Shape decoratedShape;
public ShapeDecorator(Shape decoratedShape) {
this.decoratedShape = decoratedShape;
}
/**
* 画图形
*/
@Override
public void draw() {
decoratedShape.draw();
}
}
红色的装饰器类:
package icu.sunnyc;
/**
* @author :hc
* @date :Created in 2022/4/6 21:51
* @modified :
*/
public class RedShapeDecorator extends ShapeDecorator {
public RedShapeDecorator(Shape decoratedShape) {
super(decoratedShape);
}
@Override
public void draw() {
decoratedShape.draw();
setRedBorder(decoratedShape);
}
private void setRedBorder(Shape decoratedShape) {
System.out.println("Border Color: Red");
}
}
使用
package icu.sunnyc;
/**
* @author :hc
* @date :Created in 2022/4/6 21:53
* @modified :
*/
public class DecoratorTest {
public static void main(String[] args) {
// 不加装饰的圆
Circle circle = new Circle();
// 加了装饰的圆 有没有一种似曾相识的感觉 new BufferedReader(new FileReader(""))
RedShapeDecorator redCircle = new RedShapeDecorator(new Circle());
// 加了装饰的长方形
RedShapeDecorator redRectangle = new RedShapeDecorator(new Rectangle());
// 输出验证
circle.draw();
System.out.println("====================");
redCircle.draw();
System.out.println("====================");
redRectangle.draw();
System.out.println("====================");
}
}
运行结果
画圆
====================
画圆
Border Color: Red
====================
画一个长方形
Border Color: Red
====================
可以看到画圆和画长方形的时候都加上了红色的 Border
例子类图
![image-20220421204134482](/articles/edbb2e9c/DA89B7ef91image-20220421204134482.png)
Component:就是 Shape
ConcreteComponent: 就是 Rectangle Circle
Decorator:就是 ShapeDecorator
ConcreteDecorator:就是 RedShapeDecorator
调用时序图
![image-20220421205050403](/articles/edbb2e9c/7D3EC15fC3image-20220421205050403.png)
装饰器模式(Decorator)
https://www.powercheng.fun/articles/edbb2e9c/