You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用装饰器为文件文本读取类实现简单缓存机制?

使用装饰器模式实现Text接口的缓存优化

这问题问得恰到好处!装饰器模式天生就是用来做这种不修改原有类代码、动态增强功能的场景,完美契合开闭原则。咱们一步步来实现这个简单的缓存机制:

核心思路

装饰器模式的核心逻辑很清晰:

  • 实现与被装饰对象完全相同的接口(这里就是Text)
  • 内部持有一个被装饰的Text实例作为委托对象
  • 在目标方法中加入缓存判断逻辑,仅当缓存不存在时才调用委托对象的原方法

实现缓存装饰器

我们先写一个基础版的缓存装饰器CachedText,它会把读取到的文本内容缓存起来,后续调用直接返回缓存值:

import java.io.IOException;

public final class CachedText implements Text {
    // 被装饰的原始Text实例(比如你的TextFromFile)
    private final Text delegate;
    // 缓存的文本内容,初始为null表示未缓存
    private String cachedText;

    public CachedText(Text delegate) {
        this.delegate = delegate;
    }

    @Override
    public String asText() throws IOException {
        // 优先返回缓存:如果缓存已存在,直接返回
        if (cachedText != null) {
            return cachedText;
        }
        // 缓存未命中时,调用原始方法读取内容并缓存
        cachedText = delegate.asText();
        return cachedText;
    }
}

如何使用

使用时只需要把你的TextFromFile实例包装进CachedText即可,完全不需要改动原有类的代码:

public class Demo {
    public static void main(String[] args) throws IOException {
        // 创建原始的文件读取对象
        Text rawFileText = new TextFromFile("data.txt");
        // 用缓存装饰器包装它
        Text cachedFileText = new CachedText(rawFileText);

        // 第一次调用:会实际读取文件并缓存内容
        String firstResult = cachedFileText.asText();
        // 第二次及以后调用:直接返回缓存,不会再读取文件
        String secondResult = cachedFileText.asText();
    }
}

进阶优化(可选)

上面的基础版缓存是“静态”的,如果文件内容更新了,缓存不会自动刷新。如果需要处理这种场景,可以添加文件修改时间的检查,实现自动刷新缓存:

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.FileTime;

public final class AutoRefreshCachedText implements Text {
    private final Text delegate;
    private String cachedText;
    private FileTime lastFileModified;
    private final Path filePath;

    // 这里需要TextFromFile暴露路径,或者直接传入路径
    public AutoRefreshCachedText(TextFromFile fileText) {
        this.delegate = fileText;
        this.filePath = Paths.get(fileText.path); // 可以给TextFromFile加一个getPath()方法替代直接访问字段
    }

    @Override
    public String asText() throws IOException {
        FileTime currentModifiedTime = Files.getLastModifiedTime(filePath);
        // 如果缓存不存在,或者文件已修改,重新读取并更新缓存
        if (cachedText == null || !currentModifiedTime.equals(lastFileModified)) {
            cachedText = delegate.asText();
            lastFileModified = currentModifiedTime;
        }
        return cachedText;
    }
}

这种方式既保留了原有类的核心功能,又通过装饰器灵活地添加了缓存能力,完全符合开闭原则!

内容的提问来源于stack exchange,提问作者Almas Abdrazak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 07:34:40