为对象动态的添加功能
装饰器模式
简要介绍
就是为了动态的给某个类添加功能
使用场景
不想增加子类的时候,想要扩展某个类的功能,就使用装饰器模式
比如说有一个长方形类,还有一个圆形类,都继承了一个形状接口,现在想给长方形和圆形执行 draw 方法的时候,不单纯是绘制形状,还要加一个红色边框的绘制
一般情况解决:长方形增加一个红色长方形子类,圆形再加一个红色圆形子类,重写 draw 方法
装饰器如何解决:装饰器抽象类实现形状接口,构造方法参数是形状接口,然后一个红色装饰器继承此抽象类,在红色装饰器类中绘制并添加红色边框功能
优点
装饰器和被装饰的类可以独立发展,不耦合,装饰器可以理解为继承的替代,动态扩展某个类功能
缺点
多层装饰会变的复杂
类图
例子
情景描述
比如说有一个长方形类,还有一个圆形类,都继承了一个形状接口,现在想给长方形和圆形执行 draw 方法的时候,不单纯是绘制形状,还要加一个红色边框的绘制
具体实现
shape 形状接口:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| package icu.sunnyc;
public interface Shape {
void draw(); }
|
长方形类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| package icu.sunnyc;
public class Rectangle implements Shape {
@Override public void draw() { System.out.println("画一个长方形"); } }
|
圆形类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| package icu.sunnyc;
public class Circle implements Shape {
@Override public void draw() { System.out.println("画圆"); } }
|
装饰器登场:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| package icu.sunnyc;
public abstract class ShapeDecorator implements Shape {
protected Shape decoratedShape;
public ShapeDecorator(Shape decoratedShape) { this.decoratedShape = decoratedShape; }
@Override public void draw() { decoratedShape.draw(); } }
|
红色的装饰器类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| package icu.sunnyc;
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"); }
}
|
使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| package icu.sunnyc;
public class DecoratorTest { public static void main(String[] args) { Circle circle = new Circle(); 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("===================="); } }
|
运行结果
1 2 3 4 5 6 7 8
| 画圆 ==================== 画圆 Border Color: Red ==================== 画一个长方形 Border Color: Red ====================
|
可以看到画圆和画长方形的时候都加上了红色的 Border
例子类图
Component:就是 Shape
ConcreteComponent: 就是 Rectangle Circle
Decorator:就是 ShapeDecorator
ConcreteDecorator:就是 RedShapeDecorator
调用时序图