Как ограничить значения перехода статуса только допустимыми значениями в Java? - PullRequest
0 голосов
/ 05 декабря 2018

Я должен реализовать проверку перехода статуса, например:

'P' -> 'W' -> 'M' -> 'F' -> 'G'
'P' -> 'I' -> 'B' -> 'M' -> 'F' -> 'G'

, где "->" обозначает «может перейти к»

Короче говоря, определенный статус может перемещаться только к определенномустатус, но не другой статус.Как и в приведенном выше примере, P может переходить в W или I, но не в любой другой статус.

Примечание: в системе имеется конечное число статусов.

Я читал о шаблоне Стратегии, ноЯ не чувствовал, что эта конкретная проблема подходит для него.Что будет лучшим способом реализовать это в Java 8?

Ответы [ 3 ]

0 голосов
/ 05 декабря 2018

Я бы предложил написать enum State, который представляет каждое доступное состояние и допустимые переходы:

enum State {
    G(Collections.emptySet()),
    F(Collections.singleton(G)),
    M(Collections.singleton(F)),
    B(Collections.singleton(M)),
    I(Collections.singleton(B)),
    W(Collections.singleton(M)),
    P(new HashSet<>(Arrays.asList(W, I)));

    private final Set<State> validTransitions;

    State(final Set<State> validTransitions) {
        this.validTransitions = validTransitions;
    }

    public State transitionTo(final State next) {
        if(!validTransitions.contains(next)) {
            throw new IllegalStateException();
        }
        return next;
    }
}

NB:

Это позволит толькодля DAG переходов состояний, если вы ссылаетесь на State в validTransitions, который еще не был объявлен, вы получите ошибку компилятора " Недопустимая прямая ссылка ".

Я рассматриваю это как преимущество, поскольку оно будет приводить в действие действительный набор состояний во время компиляции, но только , если ваши состояния ациклические .


Если выиспользуете Java 9 +

enum State {
    G(Collections.emptySet()),
    F(Set.of(G)),
    M(Set.of(F)),
    B(Set.of(M)),
    I(Set.of(B)),
    W(Set.of(M)),
    P(Set.of(W, I));

    private final Set<State> validTransitions;

    State(final Set<State> validTransitions) {
        this.validTransitions = validTransitions;
    }

    public State transitionTo(final State next) {
        if(!validTransitions.contains(next)) {
            throw new IllegalStateException();
        }
        return next;
    }
}
0 голосов
/ 05 декабря 2018

У меня было такое требование.Вот как я это решил.Идея состоит в том, чтобы поддерживать перечисление и обрабатывать следующие состояния, только если они действительны.

 public enum State {
    P {
        @Override
        public Boolean isValid(State nextState) {
            return nextState==State.W || nextState==State.I;
        }
    },
    W {
        @Override
        public Boolean isValid(State nextState) {
            return nextState==State.M;
        }
    },
    M {
        @Override
        public Boolean isValid(State nextState) {
            return nextState==State.F;
        }
    },
    I {
        @Override
        public Boolean isValid(State nextState) {
            return nextState==State.B;
        }
    },
    B {
        @Override
        public Boolean isValid(State nextState) {
            return prevState==State.M;
        }
    },
    G {
        @Override
        public Boolean isValid(State nextState) {
            return false;
        }
    },
    F {
        @Override
        public Boolean isValid(State nextState) {
            return nextState==State.G;
        }
    };

    public abstract Boolean isValid(State nextState);
    }
0 голосов
/ 05 декабря 2018

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

Вы указываете в коде, какие события допускают определенные переходы состояний.

Другими словами: вы не думаете с точки зрения «черного списка» (P не может перейти к B), но вместо этого вы явно заявляете (P может переходить к W и I, точка).

Для дальнейшего чтения см. здесь для обсуждения шаблона состояния против конечного автомата.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...