设计模式--装饰器模式

装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许你动态地将行为添加到对象中,而无需通过子类进行静态扩展。装饰器模式通过创建一个包装类,也就是装饰器,来包裹原始的类,并且可以在包裹过程中添加一些额外的功能。

核心概念

装饰器模式的核心思想是通过组合而非继承来扩展对象的功能。它允许你在不改变原始类(被装饰者)结构的情况下,动态地添加功能。

结构

  1. Component(抽象构件)

    • 定义一个对象接口,可以给这些对象动态地添加职责。
  2. ConcreteComponent(具体构件)

    • 实现Component接口的具体对象,是被装饰的对象。
  3. Decorator(装饰器抽象类)

    • 持有一个Component对象的引用,并定义一个与Component接口一致的接口。
    • 可以通过构造方法传入Component对象,动态地给Component对象添加职责。
  4. ConcreteDecorator(具体装饰器)

    • 实现Decorator抽象类,负责向对象添加新的职责。
    • 可以在调用父类方法前后执行一些额外的动作,以达到特定的目的。

示例

考虑一个咖啡店的订单系统,客户可以选择不同种类的咖啡(例如:浓缩咖啡、深度烘焙咖啡),并且可以选择添加不同的配料(例如:牛奶、摩卡)来装饰咖啡。

1. 定义抽象组件
java 复制代码
// Component: 咖啡接口
public interface Coffee {
    double getCost();  // 获取咖啡价格
    String getDescription();  // 获取咖啡描述
}
  1. 定义具体组件
java 复制代码
// ConcreteComponent: 浓缩咖啡
public class Espresso implements Coffee {
    @Override
    public double getCost() {
        return 1.99;
    }

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

// ConcreteComponent: 深度烘焙咖啡
public class DarkRoast implements Coffee {
    @Override
    public double getCost() {
        return 2.49;
    }

    @Override
    public String getDescription() {
        return "Dark Roast Coffee";
    }
}
  1. 定义装饰器抽象类
java 复制代码
// Decorator: 咖啡装饰器抽象类
public abstract class CoffeeDecorator implements Coffee {
    protected Coffee decoratedCoffee;

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

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

    @Override
    public String getDescription() {
        return decoratedCoffee.getDescription();
    }
}
  1. 定义具体装饰器类
java 复制代码
// ConcreteDecorator: 牛奶装饰器
public 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() + ", Milk"; // 添加牛奶的描述
    }
}

// ConcreteDecorator: 摩卡装饰器
public class MochaDecorator extends CoffeeDecorator {
    public MochaDecorator(Coffee coffee) {
        super(coffee);
    }

    @Override
    public double getCost() {
        return super.getCost() + 0.7; // 添加摩卡的价格
    }

    @Override
    public String getDescription() {
        return super.getDescription() + ", Mocha"; // 添加摩卡的描述
    }
}
  1. 客户端使用装饰器模式
java 复制代码
public class DecoratorPatternExample {
    public static void main(String[] args) {
        // 点一杯浓缩咖啡
        Coffee espresso = new Espresso();
        System.out.println("Cost: $" + espresso.getCost() + ", Description: " + espresso.getDescription());

        // 加牛奶
        Coffee milkEspresso = new MilkDecorator(espresso);
        System.out.println("Cost: $" + milkEspresso.getCost() + ", Description: " + milkEspresso.getDescription());

        // 加摩卡
        Coffee mochaDarkRoast = new MochaDecorator(new DarkRoast());
        System.out.println("Cost: $" + mochaDarkRoast.getCost() + ", Description: " + mochaDarkRoast.getDescription());

        // 组合装饰:浓缩咖啡 + 牛奶 + 摩卡
        Coffee espressoWithMilkAndMocha = new MochaDecorator(new MilkDecorator(new Espresso()));
        System.out.println("Cost: $" + espressoWithMilkAndMocha.getCost() + ", Description: " + espressoWithMilkAndMocha.getDescription());
    }
}
6. 解释
  • 抽象组件 (Coffee 接口):定义了咖啡的基本行为。
  • 具体组件 (Espresso, DarkRoast 类):具体的咖啡类型,实现了 Coffee 接口。
  • 装饰器抽象类 (CoffeeDecorator 类):实现了 Coffee 接口,并持有一个 Coffee 对象的引用。
  • 具体装饰器类 (MilkDecorator, MochaDecorator 类):扩展了 CoffeeDecorator 类,添加了额外的行为。
  • 客户端 (DecoratorPatternExample 类):演示了如何动态地使用装饰器模式来装饰不同种类的咖啡,并组合不同的装饰器。

总结

装饰器模式允许动态地将责任附加到对象上,通过对象的组合,可以在运行时扩展功能。它避免了静态地使用子类来扩展功能的缺点,使得系统更加灵活和可扩展。在实际开发中,装饰器模式常用于需要动态地增加或修改对象功能的场景,例如界面组件的装饰、I/O流的过滤等。

相关推荐
艾迪的技术之路12 分钟前
redisson使用lock导致死锁问题
java·后端·面试
今天背单词了吗98030 分钟前
算法学习笔记:8.Bellman-Ford 算法——从原理到实战,涵盖 LeetCode 与考研 408 例题
java·开发语言·后端·算法·最短路径问题
天天摸鱼的java工程师33 分钟前
使用 Spring Boot 整合高德地图实现路线规划功能
java·后端
东阳马生架构1 小时前
订单初版—2.生单链路中的技术问题说明文档
java
Gavynlee1 小时前
plantuml用法总结
设计模式
咖啡啡不加糖1 小时前
暴力破解漏洞与命令执行漏洞
java·后端·web安全
风象南1 小时前
SpringBoot敏感配置项加密与解密实战
java·spring boot·后端
DKPT1 小时前
Java享元模式实现方式与应用场景分析
java·笔记·学习·设计模式·享元模式
Percep_gan1 小时前
idea的使用小技巧,个人向
java·ide·intellij-idea