2010-04-26 51 views
6

我是Java的新手,並且遇到以下問題:如何根據Java中的字符串值在方法中返回不同的類型?

我創建了幾個類,它們都實現了接口「Parser」。我有一個JavaParser,PythonParser,CParser,最後是一個TextParser。

我想寫一個方法,所以它會採取一個文件或一個字符串(代表文件名),並返回給定文件擴展名的適當的分析器。

這裏是什麼,我基本上是試圖做一些僞代碼:

public Parser getParser(String filename) 
{ 
    String extension = filename.substring(filename.lastIndexOf(".")); 

    switch(extension) 
    { 
     case "py": return new PythonParser(); 
     case "java": return new JavaParser(); 
     case "c": return new CParser(); 
     default: return new TextParser(); 
    } 
} 

在一般情況下,這是處理這種情況的正確方法?另外,我應該如何處理Java不允許切換字符串的事實?我應該使用字符串的.hashcode()值嗎?

我覺得有一些設計模式或處理這個東西,但它逃避我。這是你怎麼做的?

回答

8

這被稱爲Factory method pattern,它似乎是一個很好的方式來處理您的問題。解決「Java不允許切換字符串」問題的一種方法是使用if ... else語句。

if (extension.equals("py")) { 
    return new PythonParser(); 
} 
else if(extension.equals("java")) { 
    return new JavaParser(); 
} 
else ... 
+1

對於OP:請注意使用'.equals()'而不是'=='。這很重要!谷歌「Java字符串等於」或什麼,看看爲什麼。 – MatrixFrog 2010-04-26 16:54:42

+0

提及工廠方法模式的+1。 – CoolBeans 2010-04-26 17:06:53

11
  1. 您只需使用幾個if語句此起彼伏。

  2. 您可以爲您的語言創建特殊的enum並在switch語句中使用它。

  3. 您可以使用Map其中語言是鍵和分析器的原型是值。

第3個選項對我來說看起來很有趣。該代碼如下:

return parsers.get(extention).newInstance(); 

這裏是一個小技巧實現與枚舉第二個選項:

enum Language { 

    JAVA { 
     public Parser getParser() { 
      return new JavaParser(); 
     }}, 
    PYTHON { 
     public Parser getParser() { 
      return new PythonParser(); 
     }}, 
    TEXT { 
     public Parser getParser() { 
      return new TextParser(); 
     }}; 

    public Parser getParser() { 
     return null; 
    } 

    public static Language getLanguage (String extention) { 
     try { 
      return valueOf (extention); 
     } catch (IllegalArgumentException e) { 
      return TEXT; 
     } 
    } 
} 

... 

public Parser getParser(String filename) { 
    String extension = filename.substring(filename.lastIndexOf("."));  
    return Language.getLanguage (extension).getParser(); 
} 
+4

個人而言,我更喜歡枚舉實現,因爲它允許正確的切換,並且不需要假設無參數構造函數。代碼不需要太長:Parsers.valueOf(extension).getParser(); – ig0774 2010-04-26 16:52:35

+0

提及枚舉+1。 – CoolBeans 2010-04-26 17:08:12

0

使用的界面是在這種情況下是正確的。你的接口應該公開這些方法,以便調用類不需要將自己投射到特定的解析器實現中。

關於開關盒,如果您使用jdk1.5或更高版本,您應該爲這些字符串定義枚舉,並且可以輕鬆使用swicth case。

1

您可以使用enum決定一旦哪種語言,你處理,然後圍繞使用它(也switch語句中):

enum Type { JAVA, PYTHON, CPP, C, PERL }; 

Type getType(String filename) 
{ 
    // do your if chain here 
    return JAVA; 
} 

public Parser getParser(String filename) 
{ 
    switch(getType(filename)) 
    { 
     case PYTHON: return new PythonParser(); 
     case JAVA: return new JavaParser(); 
     case C: return new CParser(); 
     default: return new TextParser(); 
    } 
} 

關於你的第一個問題:你的做法是好的,它是所謂當你擁有的東西,建立多種接口的具體實現的(在你的情況Parser)選擇其中一個在運行時工廠模式

+0

你甚至可以隱藏枚舉中的getType方法(並使枚舉頂層)以更強的分離關注 – 2010-04-26 17:29:49

+0

是的,你現在可以做到這一點,__enums__可以用作真實對象。 – Jack 2010-04-26 17:33:22

0

我想:

public Parser getParser(String filename) { 
    String extension = filename.substring(filename.lastIndexOf(".")); 

    if("py".equals(extension) ) { return new PythonParser() } 
    if("java".equals(extension)) { return new JavaParser(); } 
    if("c".equals(extension) ) { return new CParser();  } 

    return new TextParser(); 
} 

關於您的標題問題

我應該如何在一個方法基於Java中的字符串的值返回不同類型的?

你不能只返回一種類型。你可以做的是返回該類型的子類型,所以如果你的解析器是子類或者實現類/接口,上面的代碼將完美工作。

即。

public interface Parser { 
    //parser methods 
    ... 
} 
class PythonParser implements Parser { 
    // parser implementation 
    ... 
} 
class JavaParser implements Parser { 
    // parser implementation 
    ... 
} 
class CParser implements Parser { 
    // parser implementation 
    ... 
} 
1

在一般情況下,這是正確的方式來處理 這種情況?

這似乎是正確的做法,因爲PythonParserJavaParser等工具或者是Parser

而且子類,我應該如何處理這一事實 是Java不允許在 切換字符串?

使用if..else if;你不必使用hashcode或任何東西。檢查字符串的equals()方法。

我覺得有一些設計 模式或東西

yes

1

PythonParser時,JavaParser和CParser都應該解析器的子類,或者分析器可以是一個接口,他們都實行。

通過使用if/else if,您可以輕鬆解決case語句的限制。

請勿使用字符串的哈希碼。很多很多字符串映射到相同的哈希代碼,所以只是因爲extension.hashCode()==「java」.hashCode()並不一定意味着extension.equals(「java」)。這裏只有3根弦,意外碰撞的可能性很小,但是「只要我們幸運就應該在大多數時間工作」的節目都是壞消息。在這種情況下,程序可以完全正確地使用這個特定的字符串集合,然後在一段時間後添加CobolParser並突然停止工作。

有人提到使用枚舉。一般來說,使用枚舉來標識事物的「類型」比使用字符串要好得多。但是在這種情況下,你需要從文件名中提取字符串,所以你必須通過if/else if塊來運行它以將其轉換爲枚舉,然後測試枚舉。當你及時創建一個類型特定的解析器時,你不太可能保存枚舉或者再次查看它,所以我認爲你不會獲得任何東西。

+0

+1不使用哈希碼 – Pops 2010-04-26 18:36:16

相關問題