设计模式:异步处理文件常用设计模式

引言

在java中,基于系统系统性能考虑,大文件导入和导出大多采用异步模式。那么如何设计
既不会造成代码冗余也有利于后续更好的扩展呢?
以下将介绍三种不同的设计方案:

正文

1. 工厂模式 + 模板方法模式

1.1. 设计思路

  1. 使用工厂模式创建不同的文件导入处理器(如CSV导入、Excel导入等)。
  2. 抽象父类中定义模板方法,子类可以根据需要重写特定步骤。

1.2. 代码示例

// 1.1抽象父类,定义模板方法
abstract class FileImporter {
   public void importFile(String filePath) {
       parseFile(filePath);
       processData();
       storeData();
   }

   protected abstract void parseFile(String filePath);
   protected abstract void processData();
   protected abstract void storeData();
}

// 1.2具体实现类,重写相应步骤
class CSVFileImporter extends FileImporter {
   @Override
   protected void parseFile(String filePath) {
       // CSV文件解析逻辑
   }

   @Override
   protected void processData() {
       // CSV数据处理逻辑
   }

   @Override
   protected void storeData() {
       // CSV数据存储逻辑
   }
}

// 2.1工厂类,根据文件类型创建对应的导入处理器
class FileImporterFactory {
   public static FileImporter createFileImporter(String fileType) {
       if (fileType.equals("csv")) {
           return new CSVFileImporter();
       } else if (fileType.equals("excel")) {
           // Excel导入处理器的创建逻辑
       }
       //...
   }
}

// 异步处理,使用线程池执行导入任务
ExecutorService executor = Executors.newFixedThreadPool(5);

public void importFileAsync(String filePath, String fileType) {
   FileImporter fileImporter = FileImporterFactory.createFileImporter(fileType);
   executor.submit(() -> fileImporter.importFile(filePath));
}

2. 策略模式 + 观察者模式

2.1. 设计思路

  1. 使用策略模式定义不同的文件解析算法。
  2. 使用观察者模式在导入完成后通知相关的监听器

2.2. 代码示例

// 1.1定义文件解析策略接口
interface FileParserStrategy {
    void parseFile(String filePath);
}

// 1.2具体的CSV文件解析策略
class CSVFileParserStrategy implements FileParserStrategy {
    @Override
    public void parseFile(String filePath) {
        // CSV文件解析逻辑
    }
}

// 2.1定义文件导入器接口
interface FileImporter {
    void importFile(String filePath);
}

// 2.2具体的文件导入器实现
class DefaultFileImporter implements FileImporter {
    private FileParserStrategy parserStrategy;

    public DefaultFileImporter(FileParserStrategy parserStrategy) {
        this.parserStrategy = parserStrategy;
    }

    @Override
    public void importFile(String filePath) {
        parserStrategy.parseFile(filePath);
        // 其他导入逻辑
    }
}

// 3.1定义观察者接口
interface ImportCompleteListener {
    void onImportComplete();
}

// 4.1文件导入器的异步处理版本,添加观察者模式支持
class AsyncFileImporter extends DefaultFileImporter {
    private List<ImportCompleteListener> listeners = new ArrayList<>();

    public AsyncFileImporter(FileParserStrategy parserStrategy) {
        super(parserStrategy);
    }

    public void addListener(ImportCompleteListener listener) {
        listeners.add(listener);
    }

    @Override
    public void importFile(String filePath) {
        executor.submit(() -> {
            super.importFile(filePath);
            notifyListeners();
        });
    }

    private void notifyListeners() {
        for (ImportCompleteListener listener : listeners) {
            listener.onImportComplete();
        }
    }
}

// 使用示例
AsyncFileImporter csvImporter = new AsyncFileImporter(new CSVFileParserStrategy());
csvImporter.addListener(new ImportCompleteListener() {
    @Override
    public void onImportComplete() {
        System.out.println("CSV file import complete");
    }
});
csvImporter.importFile("example.csv");

3. 责任链模式 + 命令模式

3.1. 设计思路

  1. 使用责任链模式将文件导入流程拆分成多个处理节点
  2. 使用命令模式封装每个处理节点的逻辑。

3.2. 代码示例

// 1.1定义命令接口
interface ImportCommand {
    void execute();
}

// 1.2具体的文件解析命令
class FileParserCommand implements ImportCommand {
    private String filePath;

    public FileParserCommand(String filePath) {
        this.filePath = filePath;
    }

    @Override
    public void execute() {
        // 文件解析逻辑
    }
}

// 1.3具体的数据处理命令
class DataProcessorCommand implements ImportCommand {
    @Override
    public void execute() {
        // 数据处理逻辑
    }
}

// 1.3具体的数据存储命令
class DataStorageCommand implements ImportCommand {
    @Override
    public void execute() {
        // 数据存储逻辑
    }
}

// 2.1责任链节点接口
interface ImportHandler {
    void handle(ImportCommand command);
    void setNextHandler(ImportHandler nextHandler);
}

// 2.2具体的责任链节点实现
class FileParserHandler implements ImportHandler {
    private ImportHandler nextHandler;

    @Override
    public void handle(ImportCommand command) {
        if (command instanceof FileParserCommand) {
            ((FileParserCommand) command).execute();
        } else {
            if (nextHandler!= null) {
                nextHandler.handle(command);
            }
        }
    }

    @Override
    public void setNextHandler(ImportHandler nextHandler) {
        this.nextHandler = nextHandler;
    }
}

// 3.1文件导入器的异步处理版本,使用责任链模式和命令模式
class AsyncFileImporter {
    private ImportHandler fileParserHandler;

    public AsyncFileImporter() {
        fileParserHandler = new FileParserHandler();
        ImportHandler dataProcessorHandler = new DataProcessorHandler();
        ImportHandler dataStorageHandler = new DataStorageHandler();

        fileParserHandler.setNextHandler(dataProcessorHandler);
        dataProcessorHandler.setNextHandler(dataStorageHandler);
    }

    public void importFileAsync(String filePath) {
        ImportCommand command = new FileParserCommand(filePath);
        executor.submit(() -> fileParserHandler.handle(command));
    }
}

// 使用示例
AsyncFileImporter csvImporter = new AsyncFileImporter();
csvImporter.importFileAsync("example.csv");

总结

如何根据具体需求和团队的技术栈选择合适的模式。首先就是要做到熟练使用,达到在做需求时下意识浮现多种设计模式,只有这样才能合理做出技术选型,希望本文对您有所帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值