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

装饰者模式是一种替代继承的策略,用于动态地为对象添加功能。本文通过Java IO流和Spark RDD的例子解释其工作原理。在Java IO中,BufferedReader和InputStream增强了FileInputStream的功能。而在Spark中,RDD通过算子组合实现功能扩展,允许自定义处理逻辑。通过 Drink 和 Decorator 类的示例,展示了如何使用装饰者模式动态组合不同口味的咖啡,以创建各种价格和描述的饮品。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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);
   }
}

口味的实现与抽象

//装饰者: 组装口味和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); // 调味品 的价格
   }
}

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());
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

roman_日积跬步-终至千里

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值