Есть ли преимущество в использовании перечисления в 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;
    }
}

}

(Оба используют один и тот же основной метод)

Они оба кажутся мне совершенно одинаковыми. Мне просто интересно, есть ли случаи, когда перечисления лучше или строка не работает.

Спасибо.


person Community    schedule 30.01.2019    source источник


Ответы (1)


Основное преимущество Enum по сравнению с String: это более конкретный тип, поскольку Enum определяет возможные значения.
Это делает ваш код более надежным и лучше документированным.
Для FSM и более общих ограниченных значений это то, что вам нужно. поиск.
Но для проблем/областей, где возможные значения определяются во время выполнения, а не во время компиляции (извлечение из базы данных или что-то еще), Enum не лучший кандидат.

Пример использования Enum в вашем случае

С Enum он не будет компилироваться, так как REDD не объявлен в классе State enum:

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;

Перечисляемые значения — это экземпляры класса enum с собственными значениями для полей экземпляров, но также переопределяющие возможности для методов экземпляров

Это еще одно преимущество перечисления в 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();
}
person davidxxx    schedule 30.01.2019