当前位置: 首页 > 面试题库 >

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

丌官绍元
2023-03-14
问题内容

我手头有问题,但无法获得要使用的设计模式。问题是这样的:

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

甚至从一种状态到另一种状态的转变都可以在2种或更多种不同的条件下完成。

例如,在以下
情况下可以完成从状态1到状态3的转换:条件1:“ Its a Sunday”
条件2:“ Its Raining”
条件3:“ Its Raining and Sunday”
在每种条件下,可以进行状态3的处理不同。

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

非常感谢


问题答案:

显然,这是有限状态机的情况,但最好是组合条件而不是为每个组合创建新条件。我不喜欢Wikipedia上用于状态模式的Java示例,因为州了解其他州,这在很多情况下都是没有意义的。该保持的轨道过渡表
状态,适用 条件(S) ,并 国家,帮助照顾这个问题的。

我的两分钱是面向对象的有限状态机。您可以在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

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

Transition(Set<State> from, Set<Condition> conditions, Set<State> to)


 类似资料:
  • 6 状态模式总结        状态模式将一个对象在不同状态下的不同行为封装在一个个状态类中,通过设置不同的状态对象可以让环境对象拥有不同的行为,而状态转换的细节对于客户端而言是透明的,方便了客户端的使用。在实际开发中,状态模式具有较高的使用频率,在工作流和游戏开发中状态模式都得到了广泛的应用,例如公文状态的转换、游戏中角色的升级等。          1. 主要优点        状态模式的主要

  • 5 使用环境类实现状态转换        在状态模式中实现状态转换时,具体状态类可通过调用环境类Context的setState()方法进行状态的转换操作,也可以统一由环境类Context来实现状态的转换。此时,增加新的具体状态类可能需要修改其他具体状态类或者环境类的源代码,否则系统无法转换到新增状态。但是对于客户端来说,无须关心状态类,可以为环境类设置默认的状态类,而将状态的转换工作交给具体状态

  • 4 共享状态 在有些情况下,多个环境对象可能需要共享同一个状态,如果希望在系统中实现多个环境对象共享一个或多个状态对象,那么需要将这些状态对象定义为环境类的静态成员对象。 下面通过一个简单实例来说明如何实现共享状态: 如果某系统要求两个开关对象要么都处于开的状态,要么都处于关的状态,在使用时它们的状态必须保持一致,开关可以由开转换到关,也可以由关转换到开。 可以使用状态模式来实现开关的设计,其结构

  • 3 完整解决方案  Sunny软件公司开发人员使用状态模式来解决账户状态的转换问题,客户端只需要执行简单的存款和取款操作,系统根据余额将自动转换到相应的状态,其基本结构如图4所示: 图4 银行账户结构图        在图4中,Account充当环境类角色,AccountState充当抽象状态角色,NormalState、OverdraftState和RestrictedState充当具体状态角色

  • 2 状态模式概述 状态模式用于解决系统中复杂对象的状态转换以及不同状态下行为的封装问题。当系统中某个对象存在多个状态,这些状态之间可以进行转换,而且对象在不同状态下行为不相同时可以使用状态模式。状态模式将一个对象的状态从该对象中分离出来,封装到专门的状态类中,使得对象状态可以灵活变化,对于客户端而言,无须关心对象状态的转换以及对象所处的当前状态,无论对于何种状态的对象,客户端都可以一致处理。   

  •        “人有悲欢离合,月有阴晴圆缺”,包括人在内,很多事物都具有多种状态,而且在不同状态下会具有不同的行为,这些状态在特定条件下还将发生相互转换。就像水,它可以凝固成冰,也可以受热蒸发后变成水蒸汽,水可以流动,冰可以雕刻,蒸汽可以扩散。我们可以用UML状态图来描述H2O的三种状态,如图1所示: 图1 H2O的三种状态(未考虑临界点)        在软件系统中,有些对象也像水一样具有多种状