2017-04-01 88 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()那样。 –