2014-10-01 61 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