2017-04-01 85 views
-1

我經常使用一種模式來使代碼更簡單,我喜歡稱爲Power Enum,它是一種利用訪問者模式以及攜帶自定義數據的枚舉。這裏是一個Java的例子:如何用Scala中的訪客語義編寫權力枚舉?

import java.security.SecureRandom; 
import java.util.UUID; 
import java.util.stream.IntStream; 

public class PowerEnumDemo { 
    private static final SecureRandom random = new SecureRandom(); 

    public static void main(String[] args) { 
     for (int i = 0; i < 3 ; i++) { 
      final Color selected = Color.values()[random.nextInt(3)]; 
      System.out.println("Selected: " + selected); 
      System.out.println("rgb: " + selected.rgb); 
      selected.visit(); 
     } 
    } 

    public enum Color { 
     RED("0000ff") { 
      @Override 
      public void visit() { 
       IntStream.range(1, 10).forEach(System.out::println); 
      } 
     }, 
     GREEN("00ff00") { 
      @Override 
      public void visit() { 
       System.out.println(UUID.randomUUID().toString().chars().filter(c -> c == 'a').count()); 
       ; 
      } 
     }, 
     BLUE("ff0000") { 
      @Override 
      public void visit() { 
       System.out.println("Hello World"); 
      } 
     }; 
     final String rgb; 

     Color(final String rgb) { 
      this.rgb = rgb; 
     } 

     /** 
     * This is where the enum implements the visitor pattern to do special stuff. 
     */ 
     public abstract void visit(); 
    } 
} 

如果你運行這個小程序,你會看到它是如何工作的。我們不必知道選擇了哪個枚舉,並且我們不必執行任何可能令人討厭的循環。如果開發人員添加新的枚舉,他們必須定義其數據並實現訪問方法或代碼不會編譯。但是,當他們這樣做時,它將適用於所有訪問的人。

我想在斯卡拉實現這一點,但我在如何進行的損失。下面是創建一個枚舉類型,是一點點朦朧的禁制方法:

object Color extends Enumeration{ 
    type Color = Value 
    val RED, GREEN, BLUE = Value 
} 

我沒有看到的是我如何定義我的自定義數據和我的抽象的訪問方法,讓每個VAL實現訪問方法。 (對於那些沒有在java例子中得到它的人來說,每個枚舉都是Color Color枚舉的一個子類型)。所以你們中的任何一個scala大師都可以得到這個工作嗎? :-)

+1

在http://pedrorijo.com/blog/scala-enums/和http://pedrorijo.com/blog/scala-enums-part2/上描述的scala枚舉的幾種替代方法。希望它有幫助 – pedrorijo91

+0

如果它出現了,那將會很棒。我剛剛就這個問題發表了評論。仍然會很高興知道在此期間該做什麼。 –

+1

這裏沒有任何與訪客模式相關的內容。這只是一種普通的子類化,通過方法重寫的方式具有特定的行爲定義。你可以堅持香草密封特徵或使用enumeratum(https://github.com/lloydmeta/enumeratum)。另外,你是否可以編輯/改寫問題,以便它不涉及訪問者模式?這將顯着減少回答人員和尋找類似問題的人員之間的混淆。 – tkroman

回答

5

對於Scala中的枚舉,我會用密封特性代替Enumeration類。特別是對於這樣的用例。

sealed trait Color { 
    def visit: Unit 
    def rgb: String 
} 
object Color { 
    case object RED extends Color { 
    def visit = println("Hello World!") 
    val rgb = "ff0000" 
    } 
    .... 
} 
+0

這就是我最終做的,但想知道是否有更好的方法。顯然,這個枚舉的許多方面都不像可以說Color.values()那樣。 –