装饰器模式(Decorator)

为对象动态的添加功能

装饰器模式

简要介绍

就是为了动态的给某个类添加功能

使用场景

不想增加子类的时候,想要扩展某个类的功能,就使用装饰器模式

比如说有一个长方形类,还有一个圆形类,都继承了一个形状接口,现在想给长方形和圆形执行 draw 方法的时候,不单纯是绘制形状,还要加一个红色边框的绘制

一般情况解决:长方形增加一个红色长方形子类,圆形再加一个红色圆形子类,重写 draw 方法

装饰器如何解决:装饰器抽象类实现形状接口,构造方法参数是形状接口,然后一个红色装饰器继承此抽象类,在红色装饰器类中绘制并添加红色边框功能

优点

装饰器和被装饰的类可以独立发展,不耦合,装饰器可以理解为继承的替代,动态扩展某个类功能

缺点

多层装饰会变的复杂

类图

例子

情景描述

比如说有一个长方形类,还有一个圆形类,都继承了一个形状接口,现在想给长方形和圆形执行 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

例子类图

Component:就是 Shape

ConcreteComponent: 就是 Rectangle Circle

Decorator:就是 ShapeDecorator

ConcreteDecorator:就是 RedShapeDecorator

调用时序图


装饰器模式(Decorator)
https://www.powercheng.fun/articles/edbb2e9c/
作者
powercheng
发布于
2022年4月21日
许可协议