引言
在java中,基于系统系统性能考虑,大文件导入和导出大多采用异步模式。那么如何设计
既不会造成代码冗余也有利于后续更好的扩展呢?
以下将介绍三种不同的设计方案:
正文
1. 工厂模式 + 模板方法模式
1.1. 设计思路
- 使用
工厂模式
创建不同的文件导入处理器
(如CSV导入、Excel导入等)。 - 在
抽象父类中定义模板方法
,子类可以根据需要重写特定步骤。
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. 设计思路
- 使用
策略模式
定义不同的文件解析
算法。 - 使用
观察者模式
在导入完成后通知相关的监听器
。
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. 设计思路
- 使用
责任链模式
将文件导入流程拆分成多个处理节点
。 - 使用
命令模式
封装每个处理节点的逻辑。
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");
总结
如何根据具体需求和团队的技术栈选择合适的模式。首先就是要做到熟练使用,达到在做需求时下意识浮现多种设计模式,只有这样才能合理做出技术选型,希望本文对您有所帮助。