405. Java 文件操作基础 - 装饰者模式与 I/O Streams

14 阅读2分钟

405. Java 文件操作基础 - 装饰者模式与 I/O Streams

1️⃣ 装饰者模式的目的

  • 装饰者模式(Decorator Pattern)23 种 GoF 设计模式之一。
  • Java I/O API 充分利用装饰者模式,扩展或修改已有类的行为,而无需修改原有类。
  • 优点:
    • 动态扩展功能
    • 保持类的开放-封闭原则(Open/Closed Principle)
    • 可以组合不同功能的装饰器(Decorator)

核心思想:把一个对象“包裹”起来,在保留原功能的基础上增加新功能。


2️⃣ Reader 类层次结构

          Reader (抽象类)
             │
   ┌─────────┴─────────┐
   │                   │
CharArrayReader      FileReader  ... (StringReader 等)
   │
BufferedReader (装饰器)
   │
LineNumberReader (装饰器)

📌 核心概念

  1. Reader
    • 抽象基类,定义了读取字符的基本操作
  2. FileReader / CharArrayReader / StringReader
    • 提供具体数据源:文件、字符数组或字符串
  3. BufferedReader
    • 是 Reader 的装饰器,需要一个 Reader 实例作为委托(delegate)
    • 提供缓冲、按行读取、性能优化等功能
  4. LineNumberReader
    • 继承 BufferedReader,也是装饰器
    • 在原有功能基础上增加行号跟踪

3️⃣ 装饰者模式的关键点

  • 组合优先于继承
    • BufferedReader 内部保存一个 Reader 对象,而不是继承 FileReader 的具体实现
  • 增加功能而不修改原类
    • 例如 BufferedReader 可以提供 readLine() 方法,而 FileReader 并没有
  • 可以多层嵌套
    • 例如 new LineNumberReader(new BufferedReader(new FileReader("file.txt")))

4️⃣ 示例代码:按行读取文件并打印行号

import java.io.*;

public class DecoratorIODemo {
    public static void main(String[] args) {
        File file = new File("sample.txt");

        try (LineNumberReader lnr = 
                new LineNumberReader(
                    new BufferedReader(
                        new FileReader(file)))) {

            String line;
            while ((line = lnr.readLine()) != null) {
                System.out.println("Line " + lnr.getLineNumber() + ": " + line);
            }

        } catch (IOException e) {
            System.err.println("I/O Exception: " + e.getMessage());
        }
    }
}

✅ 讲解

  1. FileReader → 读取文件
  2. BufferedReader → 增加缓冲,提高效率
  3. LineNumberReader → 增加行号功能
  4. 多层装饰器组合
    • 可以根据需要自由组合 Reader 功能
    • 保留原始对象的行为,同时扩展新功能

5️⃣ 小结

  • Java I/O API 使用装饰者模式极大增强灵活性
  • 常见装饰器:
    • BufferedReader / BufferedWriter → 缓冲、按行处理
    • LineNumberReader → 行号追踪
    • PrintWriter → 格式化输出
  • 核心点:
    • 装饰器 接受一个 Reader/Writer 作为委托
    • 装饰器可以 扩展或覆盖原有方法
    • 可以多层嵌套,功能可组合