2014-10-01 54 views
1

我有一个enum其中每个成员都是Set<String>,即下面是我的代码:Java的设计问题:枚举与基础类

// Guava used only for the ease of "Sets<E>.newHashSet(E... elements)", no other 
// reason. 
// For pre-Java8 code, the toString() method needs to be changed. 
public enum MyEnum { 
    MemberOne(Sets.newHashSet("this", "is", "the", "first", "member")), 
    MemberTwo(Sets.newHashSet("this", "is", "the", "second", "member", "and", "it", 
          "has", "some", "more", "words")); 

    private Set<String> elements; 

    private MyEnum(Set<String> elements) { this.elements = elements; } 

    public toString() { 
    return elements.stream().collect(Collectors.joining(", ")); 
    } 
} 

我有MyEnum因为我想只有一个非常具体的一套项目中其他地方的字符串,其他人不应使用任意Set<String>的方法。但是,我也想保留的集功能性,即,我希望能够像做

if (MyEnum.MemberOne.contains("some_random_word")) 
    doSomethingSpecificToWordsInMemberOne(); 

现在,我想添加一个方法public Set<String> toSet() { return elements; }要做到这一点,主要是因为elements不应该公开。

这是一个很好的设计方法吗?我应该做一些完全不同的事情吗?例如。有

  • 一类与一群static final Set<String>对象(我最不喜欢的选项)
  • elementspublic final(我最喜欢的,现在的选项)

我的代码具有集作为枚举成员,但我的疑问涉及Set<String>被其他一些类别取代的情况。

回答

4

由于这是一个enum它是有意义的元素为public final。为了避免出现问题,你可以确保一个附加的约束:

public final Set<String> elements; 

private MyEnum(Set<String> elements) { 
    this.elements = Collections.unmodifiableSet(elements); 
} 

所以,你将仍然可以调用改变set方法,但你会得到一个UnsupportedOperationException。如果您希望编译时间安全,您应该桥接应该提供给客户端的集合的方法,而不是更多。

private final Set<String> elements; 

public boolean contains(String string) { return elements.contains(string); } 
public String[] elements() { return elements.toArray(new String[elements.size()]; } 
... 
+1

好的答案,尤其是,使用unmodifiableSet。 – Sbodd 2014-10-01 22:25:15

+1

+1我也建议使用'Set >'而不是'Set ''但是那只是我。 – OldCurmudgeon 2014-10-01 22:38:50

+0

@OldCurmudgeon:你能解释一下吗?我正在查看'EnumSet'的源代码,我直觉地感觉到'Set >'应该是我所做的,但是在尝试实现它时,我感到非常困惑并放弃了。指向良好的教程/例子也将不胜感激。谷歌搜索在这里没有太大的帮助。 – 2014-10-01 22:46:52