23种设计模式——装饰器模式(Decorator Pattern)详解

✅作者简介:大家好,我是 Meteors., 向往着更加简洁高效的代码写法与编程方式,持续分享Java技术内容。
🍎个人主页:Meteors.的博客
💞当前专栏:设计模式
✨特色专栏:知识分享
🥭本文内容:23种设计模式------装饰器模式(Decorator Pattern)
📚 ** ps ** :阅读文章如果有问题或者疑惑,欢迎在评论区提问或指出。


目录

[一. 背景](#一. 背景)

[二. 简介](#二. 简介)

[三. 特点](#三. 特点)

[四. 适用场景](#四. 适用场景)

[五. 代码示例](#五. 代码示例)

[六. 总结](#六. 总结)


一. 背景

刚学习这个设计模式感觉它和工厂模式长的很像(都有一个抽象类)。但具体观察,发现它最大的不同------套娃(一个抽象装饰器类,里面有基类变量和参数为基类变量的构造方法,之后每次继承装饰器,并传入这个变量,就能得到一个新的装饰器.......你可能会问这样"套娃"的新类有什么不同?其实每次继承的时候,它还会重写其它方法,对方法进行设定)


二. 简介

装饰器模式是一种结构型设计模式,它允许向一个现有的对象添加新的功能,同时又不改变其结构。这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。


三. 特点

  • 动态地为对象添加功能
  • 比继承更灵活(避免继承导致的子类膨胀问题)
  • 装饰类和被装饰类可以独立发展,不会相互耦合
  • 符合"开闭原则"(对扩展开放,对修改关闭)

四. 适用场景

  • 需要在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责
  • 需要动态添加功能,也能动态撤销功能
  • 当不能采用继承的方式对系统进行扩充时

五. 代码示例

java 复制代码
// 抽象组件
interface Coffee {
    double getCost();
    String getDescription();
}

// 具体组件
class SimpleCoffee implements Coffee {
    @Override
    public double getCost() {
        return 1.0;
    }

    @Override
    public String getDescription() {
        return "Simple coffee";
    }
}

// 抽象装饰器
abstract class CoffeeDecorator implements Coffee {
    protected final Coffee decoratedCoffee;

    public CoffeeDecorator(Coffee coffee) {
        this.decoratedCoffee = coffee;
    }

    @Override
    public double getCost() {
        return decoratedCoffee.getCost();
    }

    @Override
    public String getDescription() {
        return decoratedCoffee.getDescription();
    }
}

// 具体装饰器 - 加牛奶
class MilkDecorator extends CoffeeDecorator {
    public MilkDecorator(Coffee coffee) {
        super(coffee);
    }

    @Override
    public double getCost() {
        return super.getCost() + 0.5;
    }

    @Override
    public String getDescription() {
        return super.getDescription() + ", with milk";
    }
}

// 具体装饰器 - 加糖
class SugarDecorator extends CoffeeDecorator {
    public SugarDecorator(Coffee coffee) {
        super(coffee);
    }

    @Override
    public double getCost() {
        return super.getCost() + 0.2;
    }

    @Override
    public String getDescription() {
        return super.getDescription() + ", with sugar";
    }
}

// 使用示例
public class DecoratorPatternDemo {
    public static void main(String[] args) {
        Coffee simpleCoffee = new SimpleCoffee();
        System.out.println("Cost: " + simpleCoffee.getCost() + "; Description: " + simpleCoffee.getDescription());

        Coffee milkCoffee = new MilkDecorator(simpleCoffee);
        System.out.println("Cost: " + milkCoffee.getCost() + "; Description: " + milkCoffee.getDescription());

        Coffee sugarMilkCoffee = new SugarDecorator(milkCoffee);
        System.out.println("Cost: " + sugarMilkCoffee.getCost() + "; Description: " + sugarMilkCoffee.getDescription());
    }
}

六. 总结

装饰器模式通过组合而非继承的方式扩展对象的功能,提供了比继承更有弹性的替代方案。在Java中,IO流的设计就是装饰器模式的经典应用(如BufferedReader装饰FileReader)。当需要为对象动态添加功能时,装饰器模式是一个很好的选择。


最后,

其它设计模式会陆续更新,希望文章对你有所帮助!

相关推荐
维天说42 分钟前
CLI-Switch 2026年3月版历史设计:Hook、TTY 隔离与 JSON 状态
java·服务器·json
Zane19941 小时前
并发 vs 并行:别再傻傻分不清了,一文讲透 Java 并发编程的第一课
java·后端
杨充2 小时前
11.DDD与战术建模
设计模式·开源·代码规范
杨充2 小时前
12.综合实战图片框架
设计模式·开源·代码规范
噢,我明白了2 小时前
java中Excel的导入和导出(EasyExcel)
java·开发语言·excel
吠品2 小时前
Zabbix Web界面误报Server未运行的排查与解决
java·服务器·数据库
啊湘2 小时前
天气查询API接口 按月Token鉴权 实时天气 物联网可用 文档齐全
java·后端·struts
Java内核笔记3 小时前
告别十亿美元的错误 : Spring Boot 4 空安全 (JSpecify) 实战
java·spring boot·后端
糖果店的幽灵3 小时前
langgraph的 MessagesState 解读
java·开发语言·人工智能·windows·langgraph
极光代码工作室4 小时前
基于SpringBoot的在线博客系统
java·springboot·web开发·后端开发