缓冲流及装饰者模式简介

缓冲流高效原理解析及装饰者模式简介

1.处理流简述

1.1 处理流
  1. 流的概念:流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。

    • 简而言之,流是一组有序的数据序列,将数据从一个地方带到另一个地方
  2. 节点流和处理流

  • 按照流的角色,流可以划分为:节点流处理流

    • 节点流:直接连接数据源的流,可以直接向数据源(特定的IO设备,如硬盘,网络,其他程序)读写数据

      • InputStreamOutputStreamReaderWriterFileInputStream

      节点流

    • 处理流:在节点流的基础上,再套接一层增加更多功能,套接在节点流上的就是处理流

      • 缓冲流:BufferedInputStreanBufferedOutputStreamBufferedReaderBufferedWriter 增加缓冲功能,避免频繁读写硬盘。

      • 转换流:InputStreamReaderOutputStreamReader实现字节流和字符流之间的转换。

      • 数据流: DataInputStreamDataOutputStream 等-提供将基础数据类型写入到文件中,或者读取出来

        处理流

2.缓冲流高效原理图解

2.1 缓冲流概述
  • 缓冲流:一次读很多字节,但不向磁盘中写入,只是先放到内存里。等凑够了缓冲区大小的时候一次性写入磁盘,这种方式可以减少磁盘操作次数,速度就会提高很多

  • 缓冲流的基本原理,是在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO次数,从而提高读写的效率

2.2 缓冲流案例
public class BufferedDemo01 {

    public static void main(String[] args) throws IOException {
		bufferedStreamTest01();
    }
    
    /**
     * 缓冲流测试
     */
    public static void bufferedStreamTest01() throws IOException {
        long start = System.currentTimeMillis();
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\\Temp\\eclipse.zip"));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("D:\\Temp\\eclipse-2.zip"));
        byte[] bytes = new byte[1024];
        int len = -1;
        while ((len = bis.read(bytes)) != -1) {
            bos.write(bytes, 0, len);
        }
        bos.close();
        bis.close();

        long end = System.currentTimeMillis();
        System.out.println("【缓冲流】文件拷贝耗费时间:" + (end - start));

    }

}
  • 运行结果
【缓冲流】文件拷贝耗费时间:377ms
2.3 高效原理图解

缓冲流

  • 基本原理,是在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO次数,从而提高读写的效率

  • 内存的执行效率高于硬盘的执行效率,所以需要减少与硬盘的交互次数,便可提高IO效率

    • 基本流:一次读写一个或者少量数据,与硬盘交互次数多,效率低
    • 缓冲流:通过内存缓存区,一次与硬盘读写大量数据,与硬盘交互次数低,效率高
  • 辅助理解:

    • 快递员跑腿送快递:一次一个快递,往返于仓库与客户住址之间
    • 快递员配车送快递:一次一车快递,往返于仓库与客户住址之间

3.装饰者模式简介

3.1 装饰者模式概述
  • 装饰器模式(Decorator Pattern):又名包装(Wrapper)模式,允许向一个现有的对象添加新的功能,同时又不改变其结构,这种类型的设计模式属于结构型模式
    • 这种模式创建了一个装饰类,用来包装原有的类
    • 在保持类方法签名完整性的前提下,提供了额外的功能
    • 装饰器模式是继承关系的一个替代方案

注:装饰者和被装饰者对象需要有相同的超类型,因为装饰者和被装饰者必须是一样的类型,这里利用继承是为了达到类型匹配,而不是利用继承获得行为。

  • 装饰者模式与继承:都是对类的功能进行增强或拓展,区别如下
    • 利用继承设计子类
      1. 只能在编译时静态决定
      2. 并且所有子类都会继承相同的行为
    • 利用装饰者
      • 可以实现新的装饰者增加新的行为而不用修改现有代码,而如果单纯依赖继承,每当需要新行为时,还得修改现有的代码
      • 被装饰者可以在任何时候被装饰,所以可以在运行时动态地、不限量地用你喜欢的装饰者来装饰对象
3.2 装饰者模式实例
  • 普通手机(被装饰者)与智能手机(装饰者)实例
  1. 首先定义一个装饰者和被装饰者的抽象超类Phone

    /**
     * 超类:手机类
     *      功能:打电话,发短信
     */
    public abstract class Phone {
    
        abstract String call();
    
        abstract String sendMsg();
    
    }
    
  2. 然后定义一个具体被装饰者类CommonPhone

    public class CommonPhone extends Phone {
    
        @Override
        public String call() {
            return "能语音";
        }
    
        @Override
        public String sendMsg() {
            return "短信聊天";
        }
    }
    
  3. 再定义一个装饰者类SmartPhone

    1. 保留原有功能:短信聊天
    2. 增强电话功能:可视频
    public class SmartPhone extends Phone {
    
        private Phone phone;
    
        public SmartPhone(Phone phone) {
            this.phone = phone;
        }
    
        @Override
        public String call() {
            // 增强原来的语音通话功能
            return phone.call() + ",能视频";
        }
    
        @Override
        public String sendMsg() {
            return this.phone.sendMsg();
        }
    }
    
  4. 还可以继续拓展手机的功能,如再定义一个二代智能手机SmarterPhone

    1. 保留原有功能:短信聊天
    2. 增强电话功能:除了语音、可视频,还可以支持多人通话
    public class SmarterPhone extends Phone {
    
        private Phone phone;
    
        public SmarterPhone(Phone phone) {
            this.phone = phone;
        }
    
        @Override
        public String call() {
            return phone.call() + ",支持多人";
        }
    
        @Override
        public String sendMsg() {
            return this.phone.sendMsg();
        }
    }
    
  5. 测试:

    public class PhoneDemo {
        public static void main(String[] args) {
    
            Phone phone = new CommonPhone();
            System.out.println("【普通手机】" + phone.call() + "; " + phone.sendMsg());
    
            SmartPhone smartPhone = new SmartPhone(phone);
            System.out.println("【智能手机】" + smartPhone.call() + "; " + smartPhone.sendMsg());
    
            SmarterPhone smarterPhone = new SmarterPhone(smartPhone);
            System.out.println("【二代智能手机】" + smarterPhone.call() + "; " + smarterPhone.sendMsg());
    
        }
    }
    
    • 运行结果:
    【普通手机】能语音; 短信聊天
    【智能手机】能语音,能视频; 短信聊天
    【二代智能手机】能语音,能视频,支持多人; 短信聊天
    
    • 可见,装饰者模式可以非常灵活地动态地给被装饰者添加新行为
    • 与此同时,它的缺点也显现出来了,那就是必须管理好更多的对象
  • 补充:

    • java.IO类中就是采用装饰者模式,层层加强得到缓冲流
    // new BufferedReader(Reader in)
    BufferedReader in = 
        new BufferedReader(new InputStreamReader(new FileInputStream(String name)));
    // new BufferedWriter(Writer out)
    BufferedWritr out = 
        new BufferedWriter(new OutputStreamWriter(new FileOutStream(String name)))
    
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值