2011-11-26 49 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的值。 –