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

基于Apache POI与OpenCSV的文件读取器设计模式优化问询

解决方案:优化文件读取模块的接口设计与模式应用

针对你遇到的接口方法冗余问题,以下几种设计思路和模式可以解决该问题:

1. 基于泛型的通用接口(单一职责)

将接口改为泛型化设计,让实现类仅处理自身支持的DTO类型,避免冗余方法:

定义泛型接口

public interface FileReadable<T> {
    void open(String filePath);
    void close();
    List<T> read(Class<T> dtoType);
}

CsvReader实现

public class CsvReader implements FileReadable<Object> {
    private CSVReader csvReader;

    @Override
    public void open(String filePath) {
        // 初始化OpenCSV读取器逻辑
    }

    @Override
    public void close() {
        // 关闭资源逻辑
    }

    @Override
    @SuppressWarnings("unchecked")
    public List<Object> read(Class<?> dtoType) {
        if (dtoType == CsvDto1.class) {
            return (List<Object>) readCsvDto1();
        } else if (dtoType == CsvDto2.class) {
            return (List<Object>) readCsvDto2();
        }
        throw new IllegalArgumentException("不支持的DTO类型");
    }

    // 原get1()逻辑封装为私有方法
    private List<CsvDto1> readCsvDto1() {
        // 读取并转换为CsvDto1列表
    }

    // 原get2()逻辑封装为私有方法
    private List<CsvDto2> readCsvDto2() {
        // 读取并转换为CsvDto2列表
    }
}

ExcelReader的实现逻辑类似,仅处理ExlDto1和ExlDto2类型即可。

2. 接口拆分(接口隔离原则)

把原有的大接口拆分为多个职责单一的小接口,让实现类仅实现自身需要的接口:

定义拆分后的接口

// 通用文件操作接口(仅包含open/close)
public interface FileOperable {
    void open(String filePath);
    void close();
}

// CSV专属读取接口
public interface CsvReadable extends FileOperable {
    List<CsvDto1> get1();
    List<CsvDto2> get2();
}

// Excel专属读取接口
public interface ExcelReadable extends FileOperable {
    List<ExlDto1> get3();
    List<ExlDto2> get4();
}

实现类适配

public class CsvReader implements CsvReadable {
    // 实现open、close、get1、get2方法
}

public class ExcelReader implements ExcelReadable {
    // 实现open、close、get3、get4方法
}

这种方式完全避免了冗余方法,每个实现类只承担自身的职责。

3. 策略+工厂模式(统一调用入口)

如果业务层需要统一的调用方式,可以用策略模式封装不同DTO的读取逻辑,配合工厂模式根据文件和DTO类型获取对应的策略:

定义策略接口

public interface ReadStrategy<T> {
    void open(String filePath);
    void close();
    List<T> read();
}

实现具体策略

// CsvDto1读取策略
public class CsvDto1Strategy implements ReadStrategy<CsvDto1> {
    private CSVReader csvReader;

    @Override
    public void open(String filePath) {
        // 初始化逻辑
    }

    @Override
    public void close() {
        // 关闭逻辑
    }

    @Override
    public List<CsvDto1> read() {
        // 读取CsvDto1的具体逻辑
    }
}

// 同理实现CsvDto2Strategy、ExlDto1Strategy、ExlDto2Strategy

工厂类获取策略

public class ReadStrategyFactory {
    @SuppressWarnings("unchecked")
    public static <T> ReadStrategy<T> getStrategy(Class<T> dtoType, String filePath) {
        if (dtoType == CsvDto1.class && filePath.endsWith(".csv")) {
            return (ReadStrategy<T>) new CsvDto1Strategy();
        } else if (dtoType == CsvDto2.class && filePath.endsWith(".csv")) {
            return (ReadStrategy<T>) new CsvDto2Strategy();
        } else if (dtoType == ExlDto1.class && filePath.endsWith(".xlsx")) {
            return (ReadStrategy<T>) new ExlDto1Strategy();
        } else if (dtoType == ExlDto2.class && filePath.endsWith(".xlsx")) {
            return (ReadStrategy<T>) new ExlDto2Strategy();
        }
        throw new IllegalArgumentException("不支持的文件或DTO类型");
    }
}

业务层调用示例

ReadStrategy<CsvDto1> strategy = ReadStrategyFactory.getStrategy(CsvDto1.class, "data.csv");
strategy.open("data.csv");
List<CsvDto1> dataList = strategy.read();
strategy.close();

4. 适配器模式(兼容原有代码)

如果不想修改已有的CsvReader和ExcelReader结构,可以用适配器模式将它们适配到通用接口:

定义通用接口

public interface GenericReader<T> {
    void open(String filePath);
    void close();
    List<T> read();
}

实现适配器

// CsvDto1的适配器
public class CsvDto1Adapter implements GenericReader<CsvDto1> {
    private CsvReader csvReader;

    public CsvDto1Adapter(CsvReader csvReader) {
        this.csvReader = csvReader;
    }

    @Override
    public void open(String filePath) {
        csvReader.open(filePath);
    }

    @Override
    public void close() {
        csvReader.close();
    }

    @Override
    public List<CsvDto1> read() {
        return csvReader.get1();
    }
}

通过适配器,既保留原有类的逻辑,又能适配到统一接口,避免冗余方法暴露。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 00:25:20