• 设计模式--装饰器模式


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

    核心概念

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

    结构

    1. Component(抽象构件)

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

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

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

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

    示例

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

    1. 定义抽象组件
    1. // Component: 咖啡接口
    2. public interface Coffee {
    3. double getCost(); // 获取咖啡价格
    4. String getDescription(); // 获取咖啡描述
    5. }

    2. 定义具体组件

    1. // ConcreteComponent: 浓缩咖啡
    2. public class Espresso implements Coffee {
    3. @Override
    4. public double getCost() {
    5. return 1.99;
    6. }
    7. @Override
    8. public String getDescription() {
    9. return "Espresso";
    10. }
    11. }
    12. // ConcreteComponent: 深度烘焙咖啡
    13. public class DarkRoast implements Coffee {
    14. @Override
    15. public double getCost() {
    16. return 2.49;
    17. }
    18. @Override
    19. public String getDescription() {
    20. return "Dark Roast Coffee";
    21. }
    22. }

    3. 定义装饰器抽象类

    1. // Decorator: 咖啡装饰器抽象类
    2. public abstract class CoffeeDecorator implements Coffee {
    3. protected Coffee decoratedCoffee;
    4. public CoffeeDecorator(Coffee coffee) {
    5. this.decoratedCoffee = coffee;
    6. }
    7. @Override
    8. public double getCost() {
    9. return decoratedCoffee.getCost();
    10. }
    11. @Override
    12. public String getDescription() {
    13. return decoratedCoffee.getDescription();
    14. }
    15. }

    4. 定义具体装饰器类

    1. // ConcreteDecorator: 牛奶装饰器
    2. public class MilkDecorator extends CoffeeDecorator {
    3. public MilkDecorator(Coffee coffee) {
    4. super(coffee);
    5. }
    6. @Override
    7. public double getCost() {
    8. return super.getCost() + 0.5; // 添加牛奶的价格
    9. }
    10. @Override
    11. public String getDescription() {
    12. return super.getDescription() + ", Milk"; // 添加牛奶的描述
    13. }
    14. }
    15. // ConcreteDecorator: 摩卡装饰器
    16. public class MochaDecorator extends CoffeeDecorator {
    17. public MochaDecorator(Coffee coffee) {
    18. super(coffee);
    19. }
    20. @Override
    21. public double getCost() {
    22. return super.getCost() + 0.7; // 添加摩卡的价格
    23. }
    24. @Override
    25. public String getDescription() {
    26. return super.getDescription() + ", Mocha"; // 添加摩卡的描述
    27. }
    28. }

    5. 客户端使用装饰器模式

    1. public class DecoratorPatternExample {
    2. public static void main(String[] args) {
    3. // 点一杯浓缩咖啡
    4. Coffee espresso = new Espresso();
    5. System.out.println("Cost: $" + espresso.getCost() + ", Description: " + espresso.getDescription());
    6. // 加牛奶
    7. Coffee milkEspresso = new MilkDecorator(espresso);
    8. System.out.println("Cost: $" + milkEspresso.getCost() + ", Description: " + milkEspresso.getDescription());
    9. // 加摩卡
    10. Coffee mochaDarkRoast = new MochaDecorator(new DarkRoast());
    11. System.out.println("Cost: $" + mochaDarkRoast.getCost() + ", Description: " + mochaDarkRoast.getDescription());
    12. // 组合装饰:浓缩咖啡 + 牛奶 + 摩卡
    13. Coffee espressoWithMilkAndMocha = new MochaDecorator(new MilkDecorator(new Espresso()));
    14. System.out.println("Cost: $" + espressoWithMilkAndMocha.getCost() + ", Description: " + espressoWithMilkAndMocha.getDescription());
    15. }
    16. }
    6. 解释
    • 抽象组件 (Coffee 接口):定义了咖啡的基本行为。
    • 具体组件 (Espresso, DarkRoast 类):具体的咖啡类型,实现了 Coffee 接口。
    • 装饰器抽象类 (CoffeeDecorator 类):实现了 Coffee 接口,并持有一个 Coffee 对象的引用。
    • 具体装饰器类 (MilkDecorator, MochaDecorator 类):扩展了 CoffeeDecorator 类,添加了额外的行为。
    • 客户端 (DecoratorPatternExample 类):演示了如何动态地使用装饰器模式来装饰不同种类的咖啡,并组合不同的装饰器。

    总结

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

  • 相关阅读:
    Kafka生产者和消费者基本操作
    【前端Vue】社交信息头条项目完整笔记第1篇:一、项目初始化【附代码文档】
    用java画一个抽奖时用的圆盘,感觉还挺好看的。
    金仓数据库KingbaseES客户端应用参考手册--3. createdb
    DolphinScheduler 3.0安装及使用
    年薪40w的高级网络工程师面试过程,面试过程不难,但你要真做过才能回答上来
    【苹果位置推相册推送】包括撤消受权或更改Apple软件中可访问服务的任何API)
    洛谷 P1075 [NOIP2012 普及组] 质因数分解
    创作者基金 11 月亮点
    uniapp:使用subNVue原生子窗体在map上层添加自定义组件
  • 原文地址:https://blog.csdn.net/weixin_46520767/article/details/139881746