美文网首页
从IO中学习装饰器模式

从IO中学习装饰器模式

作者: 何甜甜在吗 | 来源:发表于2019-10-17 14:58 被阅读0次

最近在重学IO,我们在创建输入输出流的时候总会在构造函数中嵌套很多类,比如:BufferedReader in = new BufferedReader(new FileReader(fileName));,其实这段代码就是装饰器模式的应用,那什么是装饰器模式、有什么应用场景、优缺点是什么?

装饰器模式定义

装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构,装饰器模式的类图如下:

装饰器类图
装饰器的角色介绍:
  • 装饰器抽象构件 => Component,为一个接口或抽象类
  • 具体的构建实现类 => ConcreteComponent
  • 装饰器类 => Decorator
  • 具体的装饰器类 => ConcreteDecoratorAConcreteDecoratorB,装饰器类的具体实现,里面必有一个属性指向Componet装饰器抽象构建

装饰器模式Demo

以写简历和hr读简历的例子来讲解装饰器模式

  • 抽象类或接口:Resume.java
    面向接口编程,所以选择了接口方式
    定义了一个自我介绍的方法
    public interface Resume {
        void selfIntroduce();
    }
    
  • 基本实现类:MyResume.java
    public class MyResume implements Resume {
        @Override
        public void selfIntroduce() {
            System.out.println("姓名: 何甜甜");
            System.out.println("求职方向:服务端开发");
        }
    }
    
    光有这些基本信息是不够的,需要有亮点,不然无法在寒冬求职中过简历关,所以我们得再装饰下简历,但前提要求是不动基本实现类
  • 装饰器类:Decorator.java
    public abstract class Decorator implements Resume {
        /**
         * 接口
         */
        private Resume resume;
    
        /**
         * 构造函数
         */
        public Decorator(Resume resume) {
            this.resume = resume;
        }
    
        @Override
        public void selfIntroduce() {
            //调用传入Resume实现类的方法
            resume.selfIntroduce();
        }
    }
    
  • 具体的装饰器类
    可以有多个具体的装饰器类
    • WorkExperienceDecorator.java
        public class WorkExperienceDecorator extends Decorator {
          /**
           * 构造函数
           *
           * @param resume
           */
          public WorkExperienceDecorator(Resume resume) {
              super(resume);
          }
      
          @Override
          public void selfIntroduce() {
             super.selfIntroduce();
             //在装饰一下简历,添加工作奖励
            addWorkExperience() 
          }
      
          public void addWorkExperience() {
              System.out.println("2018-2019:xxx公司打杂");
          }
        }
      
    • OtherDecorator.java
      public class OtherDecorator extends Decorator {
          /**
           * 构造函数
           *
           * @param resume
           */
          public OtherDecorator(Resume resume) {
              super(resume);
          }
      
          @Override
          public void selfIntroduce() {
              super.selfIntroduce();
              //添加其他信息,比如github、个人博客
              addOther();
          }
      
          public void addOther() {
              System.out.println("博客:https://juejin.im/user/5b8f8cc05188255c735f3f1d");
              System.out.println("github:https://github.com/TiantianUpup");
          }
      }
      
  • 测试类
    public class Test {
        public static void main(String[] args) {
            Resume resume = new MyResume();
            //1.添加工作经历
            resume = new WorkExperienceDecorator(resume);
            //2.添加github、博客
            resume = new OtherDecorator(resume);
    
            //hr读简历
            HrReader hrReader = new HrReader();
            hrReader.read(resume);
        }
    }
    

应用场景

装饰器模式就是使用在对已有的目标功能存在不足,需要增强时【不能改变已有类】,并且目标存在抽象接口
IO中应用了大量的装饰器模式,先来看一种类图:

IO类图
附:图片来源
Reader这块来讲解装饰器模式在IO中的应用
  • 抽象类
    Reader,是一个抽象类,里面定义了接口
  • 被装饰的类
    InputStreamReaderCharArrayReaderPipedReaderStringReaderFileReader
  • 装饰器类
    FilterReaderBufferedReader
  • 具体的装饰器类
    BufferedReaderPushbackReader
    FileReader尽管也在第三行,但是FileReader构不成一个具体的装饰器类,因为它不是BufferedReader的子类也不是FilterReader的子类,不持有Reader的引用
    读写IO的时候每次打开文件会非常耗时,我们可以使用BufferedReader装饰FileReader这些被装饰器类,使用缓冲提高性能

优缺点

  • 优点
    可以动态扩展一个实现类的功能而不改变原有实现类
  • 缺点
    由于使用装饰器模式,可以比使用继承关系需要较少数目的类。使用较少的类,当然使设计比较易于进行。但是另一方面,由于使用装饰器模式会产生比使用继承关系更多的对象,更多的对象会使得查错变得困难,特别是这些对象看上去都很像

和继承有啥区别

装饰器模式是多继承的一种替代方式,但是两者之间还是存在一些不同。装饰器模式比较灵活,因为它修饰哪个类是在运行时才确定的,而继承中,继承哪个类是在编写哪个继承类的时候就要确定下来的,即继承是编译时确认

相关文章

  • 从IO中学习装饰器模式

    最近在重学IO,我们在创建输入输出流的时候总会在构造函数中嵌套很多类,比如:BufferedReader in =...

  • 装饰器模式

    原文:https://czkgo.github.io/2019/08/05/装饰器模式/ 简介 装饰器模式属于结构...

  • 让你再也忘不了IO相关知识-Java IO图文详解

    1 装饰模式 Java中IO使用的是装饰模式,装饰模式在Android中很常见,比如系统的Context。 装饰模...

  • io

    io流用的是装饰者模式 字节流 inputsteam是组件接口,fliterinputsteam是装饰器的抽象父类...

  • Java装饰器模式,从IO流讲起

    从Java IO流讲起 在java中, 字节输入流InputStream和字节输出流OutputStream, 文...

  • 利用Python装饰器来组织Tensorflow代码的结构

    装饰器 定义Python装饰器 装饰器是一种设计模式, 可以使用OOP中的继承和组合实现, 而Python还直接从...

  • java IO 的知识总结

    装饰者模式 因为java的IO是基于装饰者模式设计的,所以要了解掌握IO 必须要先清楚什么事装饰者模式(装饰者模式...

  • 50 - 装饰器模式

    本文,我们通过剖析 Java IO 类的设计思想,学习一种新的结构型模式,装饰器模式。它的代码结构跟桥接模式非常相...

  • 《设计模式》之装饰器模式

    装饰器模式 装饰器模式中主要有两个角色: 装饰器(夹克,帽子) 被装饰的对象(老王) 装饰器和被装饰的对象有两个特...

  • Java IO小小的心得

    学习JAVA IO之前必须要先学习装饰模式 上面是Java中创建一个文件对象的语句,Java在IO库的设计中使用了...

网友评论

      本文标题:从IO中学习装饰器模式

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