与仅使用字符串相比,在FSM中使用枚举有好处吗?

时间:2019-01-30 12:13:35

标签: java enums switch-statement fsm

我想创建一个有限状态机,我可以找到的大多数示例代码都使用了枚举,而我只是想知道它是否比仅使用字符串或int存储状态更具优势。

带有枚举:

TrafficLight类{     枚举状态{         红,黄,绿     };

State state = State.GREEN;

public void iterate() throws InterruptedException {
    switch (this.state) {
    case RED:
        System.out.println("RED");
        Thread.sleep(1000);
        this.state = State.GREEN;
        break;

    case GREEN:
        System.out.println("GREEN");
        Thread.sleep(1000);
        this.state = State.YELLOW;
        break;

    case YELLOW:
        System.out.println("YELLOW");
        Thread.sleep(1000);
        this.state = State.RED;
        break;
    }

}

公共类主要{

public static void main(final String[] args) throws InterruptedException {

    final TrafficLight a = new TrafficLight();
    while (true) {
        a.iterate();
    }
}

}

带有字符串

公共类TrafficLight {

String state = "GREEN";

public void iterate() throws InterruptedException {
    switch (state) {
        case "RED":
            System.out.println("RED");
            Thread.sleep(1000);
            state = "GREEN";
            break;

        case "GREEN":
            System.out.println("GREEN");
            Thread.sleep(1000);
            state = "YELLOW";
            break;

        case "YELLOW":
            System.out.println("YELLOW");
            Thread.sleep(1000);
            state = "RED";
            break;
    }
}

}

(两者使用相同的main方法)

在我看来,它们似乎都是完全相同的,我只是想知道是否在某些情况下枚举更好,或者字符串不起作用。

谢谢。

2 个答案:

答案 0 :(得分:3)

Enum相比,String的主要优势是:Enum指定了可能的值,因此更具体地键入此类型。
这样可以使您的代码更健壮,也可以更好地记录。 对于FSM和更一般的有界值,这就是您要寻找的。
但是,对于在运行时而不是在编译时(从数据库等中检索)定义可能值的问题/领域,Enum不是最佳选择。

您的案件中列举枚举的示例

使用Enum时,它将不会编译,因为REDD枚举类中未声明State

case REDD:
    System.out.println("RED");
    Thread.sleep(1000);
    this.state = State.GREEN;
    break;

但是使用String时,它将编译并且无法按预期工作:

case "REDD":
    System.out.println("RED");
    Thread.sleep(1000);
    state = "GREEN";
    break;

枚举值是枚举类的实例,具有自己的实例字段值,但也具有实例方法的覆盖能力

这是FSM或任何域中枚举的另一个优点,其中枚举值与特定的属性/处理相关联,并且根据枚举值,字段值或方法行为可能有所不同。

例如,在这里我们指定行为以获取下一个过渡:

enum State {
    YELLOW(){
        @Override
        public State next() {
            return RED;
        }
    },
    RED(){
        @Override
        public State next() {
            return GREEN;
        }
    },
    GREEN(){
        @Override
        public State next() {
            return YELLOW;
        }
    };
    public abstract State next();
}

现在,枚举拥有足够的逻辑以使不再需要switch语句:

public void iterate() throws InterruptedException {
    System.out.println(state);
    Thread.sleep(1000);         
    state = state.next();
}

答案 1 :(得分:1)

枚举相对于String或Integer / int具有明显的优势,因为它可以保存有关FSM中使用的状态的其他信息。考虑对包含用户界面显示值的状态枚举进行以下扩展:

public enum State {

   RED("My Red"),
   YELLOW("My Yellow"),
   GREEN("My Green");

   private String uiValue;

   private State(String uiValue) {
       this.uiValue = uiValue;
   }

   public String getUiValue() {
       return uiValue;
   }

}

使用String或int表示您必须使用“ Magic”值来表示您的状态。相比之下,枚举是描述状态的一种优雅方式-枚举是在单个上下文中的一组值,与比较字符串相比,比较枚举更简单,更优雅。