这是一个非常常见的Java编程问题的例子。它通常使用所谓的Java工厂设计模式来解决。下面的链接对工厂模式有一个很好的简单解释 - http://www.allapplabs.com/java_design_patterns/factory_pattern.htm
还有很多其他的设计模式,您可能会发现它很有用。阅读这些内容可以让您深入了解大量Java程序员如何解决常见问题。同一作者在http://www.allapplabs.com/java_design_patterns/java_design_patterns.htm
解释了大部分常见设计模式,现在就您的具体问题。首先,POI作者使用工厂设计模式。例如,看一下下面的代码:
Workbook wb1 = WorkbookFactory.create(new FileInputStream("myXlsFile.xls"));
Workbook wb2 = WorkbookFactory.create(new FileInputStream("myXlsxFile.xlsx"));
// this prints "wb1 class = org.apache.poi.xssf.usermodel.XSSFWorkbook"
System.out.println("wb1 class = " + wb1.getClass().getName());
// this prints "wb2 class = org.apache.poi.hssf.usermodel.HSSFWorkbook"
System.out.println("wb2 class = " + wb2.getClass().getName());
所以,作为POI的用户,你处理具有相同的属性和方法相同的工作簿对象无论你正在处理XLS文件或XLSX文件。然而,根据文件类型的不同,POI的作者显然需要两种截然不同的实现。
他们是如何做到这一点,而没有太多的if语句,比如你的代码中有什么?我会重做你的榜样,告诉你如何完成同样的事情。
你会做的第一件事是定义一个类DocExtractor如下:
public abstract class DocExtractor {
// constructor
public DocExtractor(File f) {
poiFile = f;
}
// the getText method must be defined by all derived classes
public abstract String getText();
// this protected field is visible to all classes which extend DocExtractor
protected File poiFile;
}
的原因,我建议你做DocExtractor抽象的原因是你不想代码能够创建一个DocExtractor类。你使getText方法抽象的原因是你想确保扩展DocExtactor的类将定义它们自己的getText版本。希望这个推理在您阅读时会变得清晰。
您现在可以定义DocExtractor的派生类(它们“扩展”DocExtractor)。在这个例子中,我将定义两个类,一个用于doc文件,一个用于xls文件。
// this handles doc files
public class DocExtractorDoc extends DocExtractor {
// constructor
public class DocExtractorDoc(File f) {
// this calls the DocExtractor constructor which has common code for all constructors
super(f);
// put code specific to the DocExtractorDoc constructor here
}
// concrete implementation of the getText method specific to doc files
public String getText() {
// getText code for doc files goes here
}
}
// this handles xls files
public class DocExtractorXls extends DocExtractor {
// constructor
public class DocExtractorXls(File f) {
// this calls the DocExtractor constructor which has common code for all constructors
super(f);
// put code specific to the DocExtractorXls constructor here
}
// concrete implementation of the getText method specific to xls files
public String getText() {
// getText code for xls files goes here
}
}
现在定义有一个静态一个DocExtractorFactory类中创建方法:
public class DocExtractorFactory {
public static DocExtractor create(File f) {
// create the appropriate DocExtractor derived class based on the file extension
String extension = FilenameUtils.getExtension(f.getName());
if (extension.equals("doc") {
return new DocExtractorDoc(f);
} else if (extension.equals("xls") {
return new DocExtractorXls(f);
} else {
// error handling code here -- perhaps throw an exception
}
}
}
最后,这里是它使用上述类
// this actually creates a DocExtractorDoc object (but you don't care)
DocExtractor de1 = DocExtractorFactory.create(new File("myDocFile.doc"));
// this actually uses DocExtractorDoc.getText (but again you don't care)
String s1 = de1.getText();
// this actually creates a DocExtractorXls object
DocExtractor de2 = DocExtractorFactory.create(new File("myDocFile.xls"));
// this actually uses DocExtractorXls.getText
String s2 = de2.getText();
所以一些代码,我们有什么基本完成的只有一个地方有if语句,工厂创建方法。您可以根据需要创建尽可能多的DocExtractor派生类,只需编写该类的代码并对create方法进行简单更改即可。
为什么不使用[Apache Tika](http://tika.apache.org/)? Tika使用POI从办公室文件中提取文本,但是以一种常用的方式完成所有文本 – Gagravarr