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

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

1. 装饰者模式

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

适用场景:

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

装饰者模式的作用:

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

 

2. 使用案例:

2.1. java的IO流

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

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

 

2.2. spark的RDD算子

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

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

 

3. 实现装饰者

3.1. 需求描述

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

3.2. 逻辑描述

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

  • 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());

你可能感兴趣的:(设计模式,java)