设计模式问题涉及N个状态和它们之间的转换

Ami*_*mit 19 java design-patterns automata state-machine

我手边有一个问题,我没有得到使用哪种设计模式.问题是这样的:

我必须构建一个具有'N'状态的系统,并且我的系统必须根据某些条件从任何状态转换到任何其他状态.例如:在条件1下,从状态1移动到3,在条件2上从状态1移动到4.

甚至从一个状态到另一个状态的转换也可以在两个或更多个不同的条件下完成.

例如,从状态1到状态3的转换可以在以下
情况下完成:条件1:"它是星期日"
条件2:"它的下雨"
条件3:"它的下雨和星期日"
在每种情况下,状态3的处理可以是不同.

我希望我能够清楚地理解这个问题.请帮助.

非常感谢

Anu*_*rag 37

它显然是有限状态机的情况,但它更好地结合条件而不是为每个组合创建新条件.我不喜欢维基百科上的状态模式的Java示例,因为状态知道在很多场景中没有意义的其他状态.该保持的轨道过渡表状态,适用条件(S) ,并国家,帮助需要考虑这个问题的关心.

我的两美分用于面向对象的有限状态机.你可以在OO方面做一些改进,但它可以解决这个问题.

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

class State {
    String state;
}

class Condition {
    String condition;
}
Run Code Online (Sandbox Code Playgroud)

状态机可以用上述类型构造.没有错误检查,但如果在某些条件下找不到下一个状态,则可能抛出异常或其他内容.

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

并且测试运行:

编辑:根据您的评论添加一些过渡和新状态:

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
Run Code Online (Sandbox Code Playgroud)

对于一个相当大的项目使用状态机我有一段痛苦的经历.问题在于复合状态.就像你提到的复合条件(星期日和下雨)一样,技术上可能是复合状态,可以进一步细分为单位状态.在您的情况下可能会或可能不是这种情况,但仍值得一提.如果是这种情况,最好修改经典有限状态机并使用一组状态而不是单个状态来表示from和to状态.如果您的N很大,这将有助于保持理智水平不变.想想hotmail文件夹和gmail标签.转换表将显示为

Transition(Set<State> from, Set<Condition> conditions, Set<State> to)
Run Code Online (Sandbox Code Playgroud)


Toa*_*oad 13

这听起来像是有限状态机的典型用法

简而言之,状态机描述了系统可以处于的各种状态,以及它可以在哪些条件下从一个状态到另一个状态.状态机完全按照您的英文描述进行描述.它可以使用状态图正式描述

在代码中你可以制作这样的状态机:

 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;
           ....
 }
Run Code Online (Sandbox Code Playgroud)

我不确定我是否对Java有正确的语法...我更喜欢C#

  • 解释我的downvote - 从面向对象的角度来看,使用if/switch不是首选.国家模式是更加面向对象的处理国家的方式. (3认同)
  • @Bozho “纯粹”面向对象或“纯粹”功能性等没有充分的理由。使用不同或混合范式可以更好、更一致地解决某些问题。我会争辩说,如果这个例子更容易理解,那么以这种方式做某事是一个很好的理由。说它不好“因为它不是面向对象的”是一个错误的论点。为什么不是“OO”不好的东西?易于掌握 =&gt; 易于维护 =&gt; 更快修复 =&gt; 更快、更可靠的产品发布。 (2认同)

Ben*_*nny 9

不会的状态模式做的工作?