• 【设计模式】继承的替代方式:装饰者模式-通过动态的方式丰富对象功能,而不是实现大量的继承实例


    了解一些使用案例,并写一些例子,对装饰者模式有一个入门。

    1. 装饰者模式

    装饰者模式是继承关系的一个替代方案,它可以动态地将功能附加到对象上,提供了比继承更有弹性的替代方案。

    适用场景:

    需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变的不现实,这时需要装饰者模式。

    装饰者模式的作用:

    1. 可以动态地给一个对象添加一些额外的职责;
    2. 可以增加一些基础功能而组合大量的功能(这是继承实现不了的)。

     

    2. 使用案例:

    2.1. java的IO流

    在这里插入图片描述

    其中buffer附加了缓冲区的功能、InputStream附加了编码方式,而实际读取文件的还是FileInputStream,前两者只是增强或是丰富了功能。

     

    2.2. spark的RDD算子

    在这里插入图片描述
    在这里插入图片描述

    实际触发执行的是collect算子。
    与javaIO不同的是:RDD可自定义每个算子的处理逻辑:即控制抽象。而java IO如上是直接拿来用的。
    控制抽象:将封装的逻辑打包发给它,它便具有了此功能。

     

    3. 实现装饰者

    3.1. 需求描述

    在这里插入图片描述 

    3.2. 逻辑描述

    在这里插入图片描述

    • drink是咖啡种类抽象类,具体的咖啡种类可以通过继承实现;
    • decorator是装饰的逻辑:定义了具体那种咖啡和口味是如何组合的逻辑,并且根据不同的口味继承实现不同的组合逻辑
    • 通过以组合的方式可以动态实现:不同口味的各种咖啡

    咖啡的抽象与实现

    public abstract class Drink {
    
       public String des;  //要添加的口味
       private float price = 0.0f;
       
       //... set and get: des and price
       
       //计算费用的抽象方法
       //子类来实现
       public abstract float cost();
    }
    
    
    public class DeCaf extends Drink {
       public DeCaf() {
          setDes(" 无因咖啡 ");
          setPrice(1.0f);
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    口味的实现与抽象

    //装饰者: 组装口味和Drink的逻辑
    //通过继承drink使得装饰者也有drink的属性
    public class Decorator extends Drink {
        private Drink obj; //继承+组合
    
        public Decorator(Drink obj) { //组合
            this.obj = obj;
        }
    
        @Override
        public float cost() {
            // 单品价格(单品实现了父类,通过父类方法获取单品价格)+装饰价格
            return super.getPrice() + obj.cost();
        }
    
        @Override
        public String getDes() {
            // obj.getDes() 输出被装饰者的信息
            return des + " " + getPrice() + " && " + obj.getDes();
        }
    }
    
    //具体的Decorator, 这里具体指巧克力口味
    public class Chocolate extends Decorator {
    
       public Chocolate(Drink obj) {
          super(obj);
          setDes(" 巧克力 ");
          setPrice(3.0f); // 调味品 的价格
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    client调用

    Drink order2 = new DeCaf();
    
    System.out.println("order2 无因咖啡  费用 =" + order2.cost());
    System.out.println("order2 无因咖啡 描述 = " + order2.getDes());
    
    order2 = new Chocolate(order2);
    
    System.out.println("order2 无因咖啡 加入一份Chocolate  费用 =" + order2.cost());
    System.out.println("order2 无因咖啡 加入一份Chocolate  描述 = " + order2.getDes());
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
  • 相关阅读:
    MongoDB基础操作--基础工具使用
    Flink原理与实现:数据交换策略
    <C++>再识构造函数和static成员
    【数据结构】循环链表的增删查改
    Unity之ShaderGraph如何实现马赛克效果
    [StartingPoint][Tier1]Crocodile
    LeetCode155:最小栈
    ubuntu16.04 ros realsense 配置 2022.11.15
    PYTHON-模拟练习题目集合
    pandas连接oracle数据库并拉取表中数据到dataframe中、筛选当前时间(sysdate)到一天之前的所有数据(筛选一天范围数据)
  • 原文地址:https://blog.csdn.net/hiliang521/article/details/127015727