2011-11-26 50 views
2

我需要使用帶有組合框的Enum(下面顯示的值)。設計問題|枚舉來表示組合框選項

YES (shown as YES on UI, stored in DB as Y) 
NO (shown as NO on UI, stored in DB as N) 
DEFAULT (shown as "" on UI, stored in DB as null) 

枚舉方法具有執行以下 -

  1. 的toString() - 爲UI提供自定義串。 (示出了組合的選項)
  2. OptionToDB(靜態) - 轉換所選擇的選項,以分貝值(上保存/更新)
  3. DBToOption(靜態) - 一個DB值轉換爲selcted選項(在加載屏幕)

    static enum EnumOption{ 
        YES,NO,DEFAULT; 
        .... 
        public static EnumOption DBToOption(String val){ 
         if("Y".equals(val)){ 
          return YES; 
         } else if("N".equals(val)){ 
          return NO; 
         }else { 
          return DEFAULT; 
         } 
        } 
        .... 
    } 
    

它工作得很好,但與上述方法的問題是,它使用的if/else比較來推斷要返回哪個選項/ dB值。

我想將dbValue作爲字段存儲在枚舉中,但我無法減少DBToOption中的if/else。

這個if/else可以用任何方式避免使用更好的設計?

+0

另請參閱[這個問題](http://stackoverflow.com/questions/604424/java-convert-string-to-enum)及其第二個答案 –

回答

3
public enum EnumOption { 

    YES("Y"), NO("N"), DEFAULT(""); 

    private final String value; 

    private final static Map<String, EnumOption> options; 

    static { 
      options = new HashMap<String, EnumOption>(); 
      for (EnumOption opt : EnumOption.values()) { 
       options.put(opt.value, opt); 
      } 
    } 

    private EnumOption(String value) { 
      this.value = value; 
    } 

    public static EnumOption DBToOption(String val) { 
      return options.get(val) != null ? options.get(val) : DEFAULT; 
    } 
} 

這裏是證明了它的工作原理的考驗。

public void testDBToOption() {  
    assertEquals(EnumOption.NO, EnumOption.DBToOption("N")); 
    assertEquals(EnumOption.YES, EnumOption.DBToOption("Y")); 
    assertEquals(EnumOption.DEFAULT, EnumOption.DBToOption("")); 
    assertEquals(EnumOption.DEFAULT, EnumOption.DBToOption(null)); 
    assertEquals(EnumOption.DEFAULT, EnumOption.DBToOption("R")); 
} 
+0

thx這似乎是伎倆!我嘗試着使用地圖,但是我試圖從導致NPE的構造函數中設置地圖值。感謝您展示這一點。 – Nrj

4

如果您將dbValue作爲enum中的字段存儲,您可以刪除if/else並將其替換爲for循環,儘管在這種情況下我沒有看到if/elses的任何錯誤:

static enum EnumOption { 
    YES("Y"), 
    NO("N"), 
    DEFAULT(""); 

    private final String value; 

    private EnumOption(String value) { 
    this.value = value; 
    } 

    public static EnumOption DBToOption(String val) { 
    for (EnumOption opt : EnumOption.values()) { 
     if (opt.value.equals(val)) { 
     return opt; 
     } 
    } 
    return DEFAULT; 
    } 
} 
+0

是的,我同意它在這種情況下使用if/else,但是當有更多的選擇可以處理時,這將是單調乏味的。 – Nrj

0

所以你想擺脫剩餘的if/else ...你在做Object Calisthenics

你可以做到以下幾點,如果你沒有兼容性問題:

public enum EnumOption { 

    Y("Y", "YES"), 
    N("N", "NO"), 
    D("D", ""); 

    private final String dbValue; 
    private final String uiValue; 

    private EnumOption(String dbValue, String uiValue) { 
      this.dbValue = dbValue; 
      this.uiValue = uiValue; 
    } 

    public String getDbValue() { 
    return this.dbValue; 
    } 

    public String uiValue() { 
     return this.uiValue; 
    } 

    public static EnumOption getFromDb(String dbValue) { 
     return EnumOption.valueOf(dbValue); 
    } 
} 

由於每個枚舉值只能出現一次,這至少具有相同的性能,所有其他的實現。

有關自動生成的valueOf(字符串)枚舉類型的方法,而詹姆斯DW的解決方案的詳細信息,您可以在喬希布洛赫的有效的Java項目30讀了(使用枚舉而不是INT常數),頁154。

+0

你的解決方案如何從一個字符串到枚舉? –

+0

我已經更新了我的答案。當然你可以使用valueOf()而不是getFromDb()。 – DaveFar

+0

對不起,但我認爲這隻適用於等於Y,N或D的值。 –