Is there a benefit to using an enum in a FSM over just using a string?

user9549420 :

I want to create a finite state machine and most of the example code I can find uses enums and I was just wondering if it gives an advantage over just using a string or int to store the state.

With Enum:

class TrafficLight { enum State { RED, YELLOW, GREEN };

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 class Main {

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

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

}

With String

public class 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;
    }
}

}

(Both use the same main method)

They both seem to be exactly the same to me I am just wondering if there are any cases in which enums are better or a string wouldn't work.

Thanks.

davidxxx :

Main advantage for Enum over String : this is more specifically typed as Enum specifies possible values.
This makes your code both more robust and also better documented.
For a FSM and more generally bounded values, it is what you are looking for.
But for problems/domains where possible values are defined at runtime and not at compile time (retrieving from a database or whatever), Enum is not the best candidate.

Example of Enum interest in your case

With Enum, it will not compile as REDD is not declared in the State enum class:

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

But with String, it will compile and just not work as expected :

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

Enumerated values are instances of the enum class with own values for instance fields but also overriding abilities for instance methods

This is another advantage of enum in the FSM or any domain where the enumerated values are associated to specific properties/processings and where according to enumerated value, the fields values or the method behavior could differ.

For example, here we specify the behavior to get the next transition :

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();
}

Now, the enum holds enough logic to make the switch statement not needed any longer :

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

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=95521&siteId=1