美文网首页
9、结构型模式-装饰器设计模式

9、结构型模式-装饰器设计模式

作者: 日落_3d9f | 来源:发表于2021-07-17 17:19 被阅读0次

1、如虎添翼的设计模式-装饰器设计模式

简介:讲解-装饰器设计模式介绍和应用场景

  • 装饰器设计模式(Decorator Pattern)

    • 也叫包装设计模式,属于结构型模式,它是作为现有的类的一个包装,允许向一个现有的对象添加新的功能,同时又不改变其结构
    • 给对象增加功能,一般两种方式 继承或关联组合,将一个类的对象嵌入另一个对象中,由另一个对象来决定是否调用嵌入对象的行为来增强功能,这个就是装饰器模式,比继承模式更加灵活
  • 应用场景

    • 小滴课堂-老王,本来计划买跑车撩妹的,结果口袋没钱,改买自行车,为了显得突出,店家提供多种改装方案,加个大的喇叭、加个防爆胎等,经过装饰之后成为目的更明确的自行车,更能解决问题。像这种不断为对象添加装饰的模式就叫 Decorator 模式,Decorator 指的是装饰物。
装饰器设计模式 装饰器设计模式
  • 以动态、透明的方式给单个对象添加职责,但又能不改变其结构
  • JDK源码里面应用的最多的就是IO流,大量使用装饰设计模式
装饰器设计模式
  • 角色(装饰者和被装饰者有相同的超类(Component))

    • 抽象组件(Component)

      • 定义装饰方法的规范,最初的自行车,仅仅定义了自行车的API;
    • 被装饰者(ConcreteComponent)

      • Component的具体实现,也就是我们要装饰的具体对象
      • 实现了核心角色的具体自行车
    • 装饰者组件(Decorator)

      • 定义具体装饰者的行为规范, 和Component角色有相同的接口,持有组件(Component)对象的实例引用

      • 自行车组件 都有 名称和价格

    • 具体装饰物(ConcreteDecorator)

      • 负责给构件对象装饰附加的功能
      • 比如 喇叭,防爆胎

装饰器设计模式案例实战

  • 背景需求

小滴课堂-老王,由于公司发了项目奖金,不够买跑车,就先买自行车,店家里面 有小号、中号、大号等规格的自行车。
然后改造加一个喇叭,后来不够又要加多一个,一个防爆胎不够,又有两个,存在很多个随机组合的改装。
店家就苦恼了,这样的结构难搞,价格也难算,而且需求再变动,就更麻烦了。使用装饰者就可以解决这个问题

装饰器设计模式案例
  • 不采用设计模式,你会怎么做?自己试试,然后看是否够灵活

  • 采用装饰器设计模式编码实战

2、代码:

通用组件:

public interface Bike {
    String getDescription();
    int getPrice();
}

具体的被装饰者,ConcreteComponent

public class BigBike implements Bike{

    private String description = "大号自行车";

    @Override
    public String getDescription() {
        return description;
    }

    /**
     * 200元是大号自行车的价格
     * @return
     */
    @Override
    public int getPrice() {
        return 200;
    }
}

具体的被装饰者,ConcreteComponent

public class SmallBike implements Bike{

    private String description = "小号自行车";

    @Override
    public String getDescription() {
        return description;
    }

    /**
     * 100元是小号自行车的价格
     * @return
     */
    @Override
    public int getPrice() {
        return 200;
    }
}

装饰者:

public class BikeDecorator implements Bike {
    private String description = "我只是装饰器,啥都不表示,子类帮我传递";
    @Override
    public String getDescription() {
        return description;
    }
    @Override
    public int getPrice() {
        return 0;
    }
}

RSC 是防爆胎的缩写,角色 ConcreteDecorator

public class RSCBikeDecorator extends BikeDecorator {
    private String description = "增加一个防爆胎";
    private Bike bike;
    public RSCBikeDecorator(Bike bike){
        this.bike = bike;
    }
    @Override
    public String getDescription() {
        return bike.getDescription() + ","+ description;
    }

    /**
     * 100 是防爆胎的价格
     * @return
     */
    @Override
    public int getPrice() {
        return bike.getPrice() + 100;
    }
}

喇叭,角色 ConcreteDecorator

public class SuonaBikeDecorator extends BikeDecorator {
    private String description = "增加一个喇叭";
    private Bike bike;
    public SuonaBikeDecorator(Bike bike){
        this.bike = bike;
    }
    @Override
    public String getDescription() {
        return bike.getDescription() + ","+ description;
    }
    /**
     * 50 是唢呐喇叭的价格
     * @return
     */
    @Override
    public int getPrice() {
        return bike.getPrice() + 50;
    }
}

Main函数:

public class Main {
    public static void main(String[] args) {
        /**
         * 大自行车 200
         * 小自行车 100
         * 防爆胎 100
         * 喇叭 50
         */

        //选个自行车
        Bike bike = new BigBike();
        //搭配了个RSC防爆胎
        bike = new RSCBikeDecorator(bike);
        bike = new RSCBikeDecorator(bike);
        //搭配了一个喇叭
        bike = new SuonaBikeDecorator(bike);
        bike = new SuonaBikeDecorator(bike);
        System.out.println(bike.getDescription()+", 价格:"+bike.getPrice());
    }
}

执行结果:

大号自行车,增加一个防爆胎,增加一个防爆胎,增加一个喇叭,增加一个喇叭, 价格:500

  • 优点

    • 装饰模式与继承关系的目的都是要扩展对象的功能,但装饰模式可以提供比继承更多的灵活性。
    • 使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合,原有代码无须改变,符合“开闭原则”
  • 缺点

    • 装饰模式增加了许多子类,如果过度使用会使程序变得很复杂 (多层包装)
    • 增加系统的复杂度,加大学习与理解的难度
  • 装饰器模式和桥接模式对比

    • 相同点都是通过封装其他对象达到设计的目的,和对象适配器也类似,有时也叫半装饰设计模式

    • 没有装饰者和被装饰者的主次区别,桥接和被桥接者是平等的,桥接可以互换,不用继承自同一个父类

      比如例子里面的,可以是Phone持有Color,也可以是Color持有Phone

装饰器设计模式案例
  • 桥接模式不用使用同一个接口;装饰模式用同一个接口装饰,接口在父类中定义

3、讲解-装饰器设计模式在JDK源码里面应用场景

JDK源码里面的Stream IO流-装饰器设计模式应用

  • 抽象组件(Component):InputStream

    • 定义装饰方法的规范
  • 被装饰者(ConcreteComponent) : FileInputStream 、ByteArrayInputStream

    • Component的具体实现,也就是我们要装饰的具体对象
  • 装饰者组件(Decorator):FilterInputStream

    • 定义具体装饰者的行为规范, 和Component角色有相同的接口,持有组件(Component)对象的实例引用
    • 自行车组件 都有 名称和价格
  • 具体装饰物(ConcreteDecorator):BufferedInputStream、DataInputStream

    • 负责给构件对象装饰附加的功能
    • 比如 喇叭,防爆胎
image-20200929172105246
public class FileInputStream extends InputStream
{
    /* File Descriptor - handle to the open file */
    private final FileDescriptor fd;
}

持有引用

  • 应用场景

//添加了Buffer缓冲功能
InputStream inputStream = new BufferedInputStream(new FileInputStream(""));

相关文章

网友评论

      本文标题:9、结构型模式-装饰器设计模式

      本文链接:https://www.haomeiwen.com/subject/fczypltx.html