Проблема Шаблона разработки, включающая N состояния и переходы между ними

У меня есть проблема под рукой, и я не добираюсь который шаблон разработки использовать. Проблема идет как таковая:

Я должен создать систему, которая имеет состояния 'N', и моя система должна сделать переход от любого состояния до любого другого состояния в зависимости от некоторых условий. Исключая: При условии 1, перемещение от состояния 1 - 3 и при условии 2 от состояния 1 - 4.

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

Например, переход от состояния 1 для утверждения 3 может быть сделан когда:
условие 1: "Воскресенье"
условие 2: "То, что это лилось дождем"
условие 3: "То, что это лилось дождем и в воскресенье"
В каждом условии обработка в состоянии 3 может отличаться.

Я надеюсь, что смог понять проблему четко. Доброжелательная справка.

Большое спасибо

19
задан Anurag 14 January 2010 в 12:19
поделиться

5 ответов

Ясно случай с конечным автоматом, но лучше, чтобы объединить условия, а не создать новое условие для каждой комбинации. Мне не нравился пример Java за образец состояния на Википедию, как состояния знают о других состояниях, которые не имели бы смысла в большом количестве сценариев. Таблица перехода, которая отслеживает от состояние, применимое условие (условия) , и к состояние, помогает заботиться о той проблеме.

Мои два цента для object oriented-finite-state-machine. Существуют улучшения, которые вы могли сделать на передней стороне OO, но она объясняет идею.

class Transition {
    State from;
    Set<Condition> conditions;
    State to;
}

class State {
    String state;
}

class Condition {
    String condition;
}

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

class StateMachine {
    List<Transition> transitions;
    State current;

    StateMachine(State start, List<Transition> transitions) {
        this.current = start;
        this.transitions = transitions;
    }

    void apply(Set<Condition> conditions) {
        current = getNextState(conditions);
    }

    State getNextState(Set<Condition> conditions) {
        for(Transition transition : transitions) {
            boolean currentStateMatches = transition.from.equals(current);
            boolean conditionsMatch = transition.conditions.equals(conditions);
            if(currentStateMatches && conditionsMatch) {
                return transition.to;
            }
        }
        return null;
    }
}

И тестовый прогон:

Редактирование : еще С некоторыми переходами и новыми состояниями на основе вашего комментария:

State one = new State("one");
State two = new State("two");
State three = new State("three");

Condition sunday = new Condition("Sunday");
Condition raining = new Condition("Raining");
Condition notSunday = new Condition("Not Sunday");
Condition notRaining = new Condition("Not Raining");

List<Transition> transitions = new ArrayList<Transition>();
transitions.add(one, new Set(sunday), three);
transitions.add(one, new Set(sunday), two); // <<--- Invalid, cant go to two and three
transitions.add(one, new Set(raining), three);
transitions.add(one, new Set(sunday, raining), three);
transitions.add(one, new Set(notSunday, notRaining), three);

StateMachine machine = new StateMachine(one, transitions);
System.out.print(machine.current); // "one"
machine.apply(new Set(sunday, raining));
System.out.print(machine.current); // "three

у меня был горький опыт с использованием конечного автомата для довольно крупного проекта. Проблема была со сложными государствами. Точно так же, как составное условие вы упомянули (в воскресенье и льющийся дождем), могли технически быть сложные государства, которые могли далее быть разломаны на состояния единицы. Это может или не может иметь место в вашей ситуации, но все еще стоящий упоминания. Если это так, лучше изменять классический конечный автомат и использовать набор состояний вместо единственного состояния для представления от и до состояний. Если ваш N будет большим, то это поможет сохранить уровни исправности в целости. Думать папки Hotmail по сравнению с тэгами Gmail. Таблица перехода была бы затем представлена как

Transition(Set<State> from, Set<Condition> conditions, Set<State> to)
37
ответ дан 30 November 2019 в 02:10
поделиться

[разве] эти не укажет, что образец делает работу?

9
ответ дан 30 November 2019 в 02:10
поделиться

Если аргумент только входное STD :: string Как это

std::string text("Hello");
w32function(text.c_str());

Если аргумент вход / вывод Использование STD :: Vector Вместо этого:

std::string input("input");
std::vector<char> input_vec(input.begin(), input.end());
input_vec.push_back('\0');
w32function(&input_vec[0], input_vec.size());
// Now, if you want std::string again, just make one from that vector:
std::string output(&input_vec[0]);

Если аргумент - только выход также использовать STD :: Vector , как это:

// allocates _at least_ 1k and sets those to 0
std::vector<unsigned char> buffer(1024, 0);
w32function(&buffer[0], buffer.size());
// use 'buffer' vector now as you see fit

Вы также можете использовать std :: basic_string и std :: vector , если это необходимо.

Вы можете прочитать больше на тему в книге Эффективным STL Скотт Мейерс.

-121--3791990-

Первое, что я заметил в вашем примере, это состояние 3 = (состояние 1 == True && State 2 == TRUE). Это не будет масштабироваться очень хорошо, как вовлечены более возможные состояния. Если вы рассматриваете только, стоит ли идти дождь или в воскресенье, вы можете иметь в воскресенье, у вас может быть перечисление, с 4 возможными типами:

enum State { CLEAR_OTHER_DAY, RAINING_OTHER_DAY, CLEAR_SUNDAY, RAINING_SUNDAY }

Это позволит вам очистить условия чисто в блоке переключателя, когда настало время для кода. Но если вы также должны рассмотреть, тепло его на улице, вы должны добавить еще 4 значения для захвата всех возможных условий. А позже в вашем проекте ваш код может потребоваться запечатлеть больше условий, чем вы в настоящее время представите.

Что касается структуры дизайна, узор состояния и его пример Java на Wikipedia выглядят как хорошее место для начала.

Пример Википедии имеет StateContext класс со способом, называемым SetState , который принимает имя. Я подумал, что вы предложили, что вы добавляете логику определения состояния здесь, но это сделало бы вашу StateContext классом классом. Было бы лучше поставить метод определения состояния системы в классе, который бы легко узнал условия для перехода от одного государства в другое. Таким образом, если ваш проект должен измениться в будущем, и у вас есть больше государств для отслеживания или разных условий, вам нужно только поддерживать логику в одном месте.

1
ответ дан 30 November 2019 в 02:10
поделиться

Это походит на типичное использование для конечный автомат

короче говоря, конечный автомат описывает различные состояния, в которых ваша система может быть, и под которыми условиями это может пойти в зависимости от государства. Конечный автомат описан точно как ваше английское описание. И это может быть официально описано с помощью диаграммы состояний

в коде, вы могли сделать конечный автомат как это:

 enum State { Init, ShowMenu, ShowMsg, DisplayVideo, Exit };
 State state = State.Init;

 while (state != State.Exit)
 {
      switch(state)
      {
           case State.Init:
                init();
                state = State.ShowMenu;
                break;
           case State.ShowMenu:
                if(lastMenuItemSelected==1) state = State.ShowMsg;
                if(lastMenuItemSelected==2) state = State.DisplayVideo;
                break;
           case State.ShowMsg:
                ....
                break;
           ....
 }

я не уверен, получил ли я точный синтаксис, корректный для Java... Я больше в C#

13
ответ дан 30 November 2019 в 02:10
поделиться

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

Однако 3-й способ - фактически кодировать его как график, с состояниями как узлы и условия в качестве направленных ребер. Затем рисунок посетителей может использоваться для применения графика к другому применению. Это обеспечит особенно хорошо конструирует, где могут быть определены состояния и / или переходы, но, вероятно, будут более интенсивно памятью, затем жесткими кодированными станками, описанными в других ответах.

2
ответ дан 30 November 2019 в 02:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: