透过 Java IO 流学习装饰器模式

简介: 装饰器模式是结构性设计模式中的一种,结构型设计模式主要总结了一些将类或接口组合在一起的经典结构,装饰器模式用于对现有的类的功能进行增强。

装饰器模式是结构性设计模式中的一种,结构型设计模式主要总结了一些将类或接口组合在一起的经典结构,装饰器模式用于对现有的类的功能进行增强。


Java IO 中的装饰器模式


Java IO 中的类是装饰器模式的经典使用。为了读取文件中的内容,我们经常会使用如下的代码。

try (BufferedReader bis = new BufferedReader(new FileReader(new File("/Users/hkp/abc.txt")))) {
    String content = null;
    while ((content = bis.readLine()) != null) {
        System.out.println(content);
    }
}


BufferedReader 作为一个装饰器类对 Reader 类进行了增强,提供了缓存字符的能力。


考虑一个问题,BufferedReader 构造方法需要 Reader 作为参数,为什么 Java 不提供一个 BufferedFileReader 类继承 FileReader 类呢?这是因为 Reader 除了 FileReader 还有其他众多的实现类,每个实现类除了缓存可能还需要进行其他增强,如果把增强的功能进行组合创建新的类,这将导致 Java IO 中类的数量呈倍数增加。


通过将继承关系改为组合关系能够有效解决类的继承结构过于复杂的问题。


如何实现一个装饰器模式


BufferedReader 类结构大致如下。


public class BufferedReader extends Reader {
    private Reader in;
    private char cb[];
    private int nChars, nextChar;
    private static int defaultCharBufferSize = 8192;
    public BufferedReader(Reader in, int sz) {
        super(in);
        if (sz <= 0)
            throw new IllegalArgumentException("Buffer size <= 0");
        this.in = in;
        cb = new char[sz];
        nextChar = nChars = 0;
    }
    public BufferedReader(Reader in) {
        this(in, defaultCharBufferSize);
    }
    public int read() throws IOException {
    // 缓存增强
  }
}


BufferedReader 实现了 Reader 接口,并将原始 Reader 接口作为构造方法的参数,利用原始 Reader 实现接口中的方法,并在此基础上增加了缓存能力。


总结实现装饰器模式的步骤如下。


实现接口 InterF。


将接口 InterF 作为构造方法参数,保存为成员变量 target。

利用成员变量 target 实现接口 InterF 的方法,并增强其功能。

上述步骤中的接口如果为类则需要改成继承,其他保持一致。翻译上述实现装饰器的步骤为代码如下。


public interface InterF {
    void method1();
    void method2();
}
public class InterFDecorator implements InterF {
    private InterF target;
    public InterFDecorator(InterF target) {
        this.target = target;
    }
    @Override
    public void method1() {
        // 省略功能增强代码
        target.method1();
        // 省略功能增强代码
    }
    @Override
    public void method2() {
        // 省略功能增强代码
        target.method2();
        // 省略功能增强代码
    }
}


总结

装饰器模式通过将继承关系转换为组合关系,解决了类的层次结构过于复杂的问题,对于原始类可以嵌套使用多个装饰器类。装饰器模式的实现与代理模式极为相似,不同的是代理模式为了实现与原始类不同的功能,而装饰器模式则用于对原有类的功能进行增强。

目录
相关文章
|
21天前
|
安全 Java API
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
String常量池、String、StringBuffer、Stringbuilder有什么区别、List与Set的区别、ArrayList和LinkedList的区别、HashMap底层原理、ConcurrentHashMap、HashMap和Hashtable的区别、泛型擦除、ABA问题、IO多路复用、BIO、NIO、O、异常处理机制、反射
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
|
19天前
|
设计模式 架构师 Java
Java开发工程师转架构师需要学习什么
Java开发工程师转型为架构师需掌握多项技能:精通Java及框架、数据库与分布式系统;熟悉设计模式与架构模式;积累项目经验;提升沟通与领导力;持续学习新技术;培养系统设计与抽象能力;了解中间件及开发工具;并注重个人特质与职业发展。具体路径应结合个人目标与实际情况制定。
42 18
|
15天前
|
Java 大数据 API
Java 流(Stream)、文件(File)和IO的区别
Java中的流(Stream)、文件(File)和输入/输出(I/O)是处理数据的关键概念。`File`类用于基本文件操作,如创建、删除和检查文件;流则提供了数据读写的抽象机制,适用于文件、内存和网络等多种数据源;I/O涵盖更广泛的输入输出操作,包括文件I/O、网络通信等,并支持异常处理和缓冲等功能。实际开发中,这三者常结合使用,以实现高效的数据处理。例如,`File`用于管理文件路径,`Stream`用于读写数据,I/O则处理复杂的输入输出需求。
|
1月前
|
监控 Java 调度
【Java学习】多线程&JUC万字超详解
本文详细介绍了多线程的概念和三种实现方式,还有一些常见的成员方法,CPU的调动方式,多线程的生命周期,还有线程安全问题,锁和死锁的概念,以及等待唤醒机制,阻塞队列,多线程的六种状态,线程池等
105 6
【Java学习】多线程&JUC万字超详解
|
9天前
|
设计模式 Java
Java设计模式-装饰器模式(10)
Java设计模式-装饰器模式(10)
|
1月前
|
数据采集 Java 数据挖掘
Java IO异常处理:在Web爬虫开发中的实践
Java IO异常处理:在Web爬虫开发中的实践
|
2月前
|
Java 数据处理
Java IO 接口(Input)究竟隐藏着怎样的神秘用法?快来一探究竟,解锁高效编程新境界!
【8月更文挑战第22天】Java的输入输出(IO)操作至关重要,它支持从多种来源读取数据,如文件、网络等。常用输入流包括`FileInputStream`,适用于按字节读取文件;结合`BufferedInputStream`可提升读取效率。此外,通过`Socket`和相关输入流,还能实现网络数据读取。合理选用这些流能有效支持程序的数据处理需求。
28 2
|
2月前
|
XML 存储 JSON
【IO面试题 六】、 除了Java自带的序列化之外,你还了解哪些序列化工具?
除了Java自带的序列化,常见的序列化工具还包括JSON(如jackson、gson、fastjson)、Protobuf、Thrift和Avro,各具特点,适用于不同的应用场景和性能需求。
|
2月前
|
NoSQL Java Redis
【Azure Spring Cloud】Java Spring Cloud 应用部署到Azure上后,发现大量的 java.lang.NullPointerException: null at io.lettuce.core.protocol.CommandHandler.writeSingleCommand(CommandHandler.java:426) at ... 异常
【Azure Spring Cloud】Java Spring Cloud 应用部署到Azure上后,发现大量的 java.lang.NullPointerException: null at io.lettuce.core.protocol.CommandHandler.writeSingleCommand(CommandHandler.java:426) at ... 异常
|
2月前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
下一篇
无影云桌面