设计模式——装饰器模式

装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许在运行时动态地给对象添加新的职责或功能。装饰器提供了比继承更灵活的替代方案来扩展类的行为,装饰器和被装饰的对象具有相同的接口,因此可以用来代替原对象。

原理

  • 组件接口(Component): 定义了基本行为,所有具体的组件和装饰器都要实现这个接口。
  • 具体组件(Concrete Component): 是原始对象,实现了组件接口。
  • 装饰器(Decorator): 包含一个指向组件接口的引用,并通过组合的方式持有一个具体组件实例;装饰器本身也实现了组件接口,这样就可以在不修改原有接口的前提下增加额外的功能。
  • 具体装饰器(Concrete Decorator): 是装饰器的具体实现,它在实现组件接口的方法时,既可以调用被装饰对象的方法,也可以在此基础上添加新功能。

Java代码示例

java 复制代码
// 组件接口
public interface Coffee {
    double getCost();
    String getDescription();
}

// 具体组件:基础咖啡
public class SimpleCoffee implements Coffee {
    @Override
    public double getCost() {
        return 10.0;
    }

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

// 装饰器抽象类
public abstract class CoffeeDecorator implements Coffee {
    protected Coffee coffee;

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

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

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

// 具体装饰器:加糖咖啡
public class SugarCoffeeDecorator extends CoffeeDecorator {
    private static final double SUGAR_COST = 1.5;

    public SugarCoffeeDecorator(Coffee coffee) {
        super(coffee);
    }

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

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

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

        Coffee sugarCoffee = new SugarCoffeeDecorator(simpleCoffee);
        System.out.println(sugarCoffee.getDescription() + ": $" + sugarCoffee.getCost());
    }
}

想象一下你在一个咖啡店点了一杯简单的咖啡,然后又决定加糖。在现实生活中,这就像在原有的咖啡上附加了一个"加糖"的行为。在程序设计中,装饰器模式就是模拟这个过程:先创建一杯基础咖啡,然后用一个"加糖装饰器"去包裹它,使得最终得到的是带有附加功能(即加了糖)的新咖啡对象,但客户并不需要知道装饰过程,只需要按照统一的咖啡接口来操作即可。

应用场景

  • 在Java I/O库中,BufferedInputStream 和 BufferedOutputStream 就是对 InputStream 和 OutputStream 的装饰,增加了缓冲功能。
  • 在GUI编程中,按钮、文本框等控件可以通过装饰器模式添加边框、背景色等不同的外观效果。

适用性

  • 当系统需要在不影响其他对象的情况下,为单个对象添加职责或功能时。
  • 需要提供一种替代继承机制的方式来扩展对象的功能时,因为继承会带来大量的子类,而装饰器可以在运行时动态添加行为。
相关推荐
tkevinjd1 分钟前
JUC2(多线程中常用的成员方法)
java
天天摸鱼的java工程师6 分钟前
工作中 Java 程序员如何集成 AI?Spring AI、LangChain4j、JBoltAI 实战对比
java·后端
星辰_mya6 分钟前
RockerMQ之commitlog与consumequeue
java·开发语言
__万波__7 分钟前
二十三种设计模式(二十二)--策略模式
java·设计模式·策略模式
不想上班的小吕8 分钟前
采购申请创建(BAPI_PR_CREATE/BAPI_REQUISITION_CREATE)
java·服务器·数据库
专注VB编程开发20年11 分钟前
压栈顺序是反向(从右往左)的,但正因为是反向压栈,所以第一个参数反而离栈顶(ESP)最近。
java·开发语言·算法
椰汁菠萝12 分钟前
spring boot下使用gdal解析tif文件
java·native·gdal·0
better_liang12 分钟前
每日Java面试场景题知识点之-ELK日志分析
java·elk·微服务·面试题·日志分析·企业级开发
图南随笔16 分钟前
Spring Boot(二十三):RedisTemplate的Set和Sorted Set类型操作
java·spring boot·redis·后端·缓存
say_fall16 分钟前
C++ 类与对象易错点:初始化列表顺序 / 静态成员访问 / 隐式类型转换
android·java·开发语言·c++