Java设计模式之装饰器模式

概述和作用

装饰器模式是一种结构型设计模式,允许在运行时动态地给对象添加额外的功能或职责。它通过创建装饰器类来包装原始对象,从而在不修改原始类代码的情况下扩展其功能。

装饰器模式适用于以下场景:

需要动态地给对象添加功能或职责,且这些功能或职责可以随时添加和移除。

需要避免通过继承进行功能扩展,因为继承会导致类的层次结构过于复杂。

举例

假设我们有一个图形绘制系统,需要给图形添加不同的装饰效果,如边框、阴影等。我们可以使用装饰器模式来实现。

复制代码
public interface Shape {
    void draw();
}

// 圆形
public class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("绘制圆形");
    }
}

// 矩形
public class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("绘制矩形");
    }
}

public abstract class ShapeDecorator implements Shape {
    protected Shape decoratedShape;

    public ShapeDecorator(Shape decoratedShape) {
        this.decoratedShape = decoratedShape;
    }

    @Override
    public void draw() {
        decoratedShape.draw();
    }
}

// 边框装饰器
public class BorderDecorator extends ShapeDecorator {
    public BorderDecorator(Shape decoratedShape) {
        super(decoratedShape);
    }

    @Override
    public void draw() {
        super.draw();
        addBorder();
    }

    private void addBorder() {
        System.out.println("添加边框");
    }
}

// 阴影装饰器
public class ShadowDecorator extends ShapeDecorator {
    public ShadowDecorator(Shape decoratedShape) {
        super(decoratedShape);
    }

    @Override
    public void draw() {
        super.draw();
        addShadow();
    }

    private void addShadow() {
        System.out.println("添加阴影");
    }
}

public class Main {
    public static void main(String[] args) {
        Shape circle = new Circle();
        Shape rectangle = new Rectangle();

        // 给圆形添加边框
        Shape circleWithBorder = new BorderDecorator(circle);
        circleWithBorder.draw(); // 输出:绘制圆形 添加边框

        // 给矩形添加阴影
        Shape rectangleWithShadow = new ShadowDecorator(rectangle);
        rectangleWithShadow.draw(); // 输出:绘制矩形 添加阴影

        // 给圆形同时添加边框和阴影
        Shape circleWithBorderAndShadow = new ShadowDecorator(new BorderDecorator(circle));
        circleWithBorderAndShadow.draw(); // 输出:绘制圆形 添加边框 添加阴影
    }
}

优点和缺点

优点

**1.动态扩展功能:**可以在运行时动态地给对象添加功能,而无需修改原始类的代码。

**2.代码复用性高:**通过装饰器类的组合,可以灵活地组合不同的功能,避免了类的爆炸性增长。

**3.符合开闭原则:**对扩展开放,对修改封闭。可以在不修改原始类的情况下扩展其功能。

缺点

**1.可能导致设计复杂:**如果过度使用装饰器模式,可能会导致系统设计变得复杂,难以理解。

**2.装饰器组合的复杂性:**如果装饰器之间存在依赖关系,可能会导致装饰器的组合变得复杂。

不使用装饰器模式的实现方式

如果不使用装饰器模式,可以通过继承或组合的方式来实现类似的功能。

继承方式

复制代码
public class CircleWithBorder extends Circle {
    @Override
    public void draw() {
        super.draw();
        System.out.println("添加边框");
    }
}

public class CircleWithShadow extends Circle {
    @Override
    public void draw() {
        super.draw();
        System.out.println("添加阴影");
    }
}

public class CircleWithBorderAndShadow extends Circle {
    @Override
    public void draw() {
        super.draw();
        System.out.println("添加边框");
        System.out.println("添加阴影");
    }
}

组合方式

复制代码
public class CircleWithBorder {
    private Circle circle;

    public CircleWithBorder(Circle circle) {
        this.circle = circle;
    }

    public void draw() {
        circle.draw();
        System.out.println("添加边框");
    }
}

public class CircleWithShadow {
    private Circle circle;

    public CircleWithShadow(Circle circle) {
        this.circle = circle;
    }

    public void draw() {
        circle.draw();
        System.out.println("添加阴影");
    }
}

然而,这种方式会导致类的爆炸性增长,因为每一种功能组合都需要一个单独的类。而装饰器模式通过装饰器类的组合,可以更灵活地实现功能扩展。

相关推荐
北极糊的狐5 分钟前
IntelliJ IDEA插件:CodeGeeX 智能助手插件
java·ide·intellij-idea
悟能不能悟7 分钟前
jdk25结构化并发和虚拟线程如何配合使用?有什么最佳实践?
java·开发语言
熙客31 分钟前
Java8:Lambda表达式
java·开发语言
小咕聊编程34 分钟前
【含文档+PPT+源码】基于java web的篮球馆管理系统系统的设计与实现
java·开发语言
后端小张1 小时前
【JAVA 进阶】Mybatis-Plus 实战使用与最佳实践
java·spring boot·spring·spring cloud·tomcat·mybatis·mybatis plus
崎岖Qiu1 小时前
【设计模式笔记07】:迪米特法则
java·笔记·设计模式·迪米特法则
摇滚侠3 小时前
Spring Boot3零基础教程,SpringApplication 自定义 banner,笔记54
java·spring boot·笔记
青云交3 小时前
Java 大视界 -- Java 大数据机器学习模型在游戏用户行为分析与游戏平衡优化中的应用
java·大数据·机器学习·数据存储·模型构建·游戏用户行为分析·游戏平衡优化
暗武逢天6 小时前
Java导出写入固定Excel模板数据
java·导出数据·easyexcel·excel固定模板导出
摇滚侠6 小时前
Spring Boot3零基础教程,KafkaTemplate 发送消息,笔记77
java·spring boot·笔记·后端·kafka