這是一個非常常見的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