Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Design patterns 状态机和状态模式的实现之间有什么区别?_Design Patterns_Architecture_State Machine_State Pattern - Fatal编程技术网

Design patterns 状态机和状态模式的实现之间有什么区别?

Design patterns 状态机和状态模式的实现之间有什么区别?,design-patterns,architecture,state-machine,state-pattern,Design Patterns,Architecture,State Machine,State Pattern,我想知道状态机是否只是工作中的状态模式,或者这两者之间是否真的有区别 我发现了这一点,但在一天结束时,他只说状态模式使状态机过时,但没有描述与状态模式的实现相比,状态机到底是什么。状态机可以用几种方式设计和实现。一种方法是使用四人帮在书中描述的状态模式。但是还有其他模式可以实现状态机 例如,您可能想通过阅读《C/C++中的实用UML状态图》(第二版)(嵌入式系统的事件驱动编程)一书来了解Miro Samek的研究 您可能也会发现有趣的地方。我向同事们描述这种差异的方式是,状态模式是许多独立封装状

我想知道状态机是否只是工作中的状态模式,或者这两者之间是否真的有区别


我发现了这一点,但在一天结束时,他只说状态模式使状态机过时,但没有描述与状态模式的实现相比,状态机到底是什么。

状态机可以用几种方式设计和实现。一种方法是使用四人帮在书中描述的状态模式。但是还有其他模式可以实现状态机

例如,您可能想通过阅读《C/C++中的实用UML状态图》(第二版)(嵌入式系统的事件驱动编程)一书来了解Miro Samek的研究


您可能也会发现有趣的地方。

我向同事们描述这种差异的方式是,状态模式是许多独立封装状态的一种更分散的实现,而状态机则更单一。状态机的整体性意味着单个状态将更难在不同的机器中重用,并且更难将状态机分解为多个编译单元。另一方面,这种单片设计允许更好地优化状态机,并允许许多实现在表中的一个位置表示所有转换信息。这尤其适用于负责状态机架构或功能的人员不熟悉其实现的编程语言的情况。请记住,许多工程和数学专业的学生都学习过状态机,但在编程领域几乎没有受过教育。向这些类型的人展示一个包含转换、操作和保护的表格要比一页页一页的状态模式容易得多

尽管这篇文章实际上读得不错,但我在以下几点上与作者意见相左:

  • “当您使用面向对象的编程语言时,没有理由再使用状态机了。”如果您对执行速度有任何要求,这绝对不是事实
  • 作者的实现特别短或简单,或者比boost statecharts数码相机需要更少的维护,这取决于您的用例和个人喜好,但不能分类
请注意,切换状态需要分配!这会扼杀速度。这可以通过将所有状态放置在一个相邻的缓冲区中以保存一两个缓存未命中来解决。但是,这需要对作者示例进行重大更改

还要注意,不能像在静态机器中那样内联和优化未处理的事件,因为在状态模式中,它们位于动态间接层的后面。根据您的需求,这也是一个潜在的效率杀手

从维护的角度来看,应该注意,不能从一个具有状态模式的中央超级状态记录未处理的事件。另外,添加新的事件类型/处理程序函数需要向所有状态添加一个函数!我不认为维护友好。 我也更喜欢看到表中的所有转换,而不是查看每个状态的内部工作。作者是对的,添加一个状态比较容易,但非常简单,以boost statecharts为例,我只需要将该状态添加到其父-子状态列表中,这是唯一真正的区别

在速度不是问题,并且状态机的层次结构很可能保持不变的情况下,我确实使用状态模式。作者是正确的,与状态机相比,状态模式的初始实现通常更容易,而且通常更多的程序员应该使用更多的状态机

状态模式的一个论点是,它允许实现“开放-关闭”状态机,其中状态机可以在库中定义,然后由用户进行扩展,就我所知,这在主流状态机框架中是不可能的

状态机只是工作中的状态模式,或者如果这两者之间确实存在差异的话

TL;DR:想象一下,你需要用一个行为不同的状态来替换一个状态。然后想象您需要添加一个新状态

完整答案。有很大区别

状态模式对状态进行抽象,并将它们彼此分离。例如,您可以轻松地将一个特定状态替换为另一个。然而,当你需要添加一个新的状态和/或一个新的转换时,你不会乐意重写所有的状态


状态机抽象状态图本身,并将其与转换有效负载解耦。要更改特定状态,必须修复整个关系图。但是要添加状态或转换,您只需要修改图表

如果还有人感兴趣,以下是我的看法:

在状态机中,对象可以处于不同的状态,但我们并不真正关心它们在这些状态下的行为。事实上,我们只关心当对象转换到下一个状态时应用了什么操作。如果在Java中实现状态机,状态将只是一个枚举或字符串,并且将有一个带有doAction()方法的转换类

另一方面,在状态模式中,您并不真正关心转换,而是关心对象在这些状态下的行为。转换只是一个实现细节,使您的状态行为彼此解耦。每个状态都是一个单独的类,有自己的doAction()方法

说状态模式使状态机过时是不正确的。如果每个状态的行为都很重要,状态模式将很有用,例如在游戏程序中
     inner class StateContext : State {

       private var stateContext: State? = null
       private var lockState: Boolean = false

       fun isLockState(): Boolean {
           return lockState
       }

       fun setLockState(lockState: Boolean): StateContext {
           this.lockState = lockState//no further actions allowed. useful if you need to permenatley lock out the user from changing state.
           return this
       }

       fun getState(): State? {
           return this.stateContext
       }

       fun setState(state: State): StateContext {
           if (!lockState) this.stateContext = state
           return this
       }

       override fun doAction() {
           this.stateContext?.doAction()
       }
   }
public enum LeaveRequestState {

Submitted {
    @Override
    public LeaveRequestState nextState() {
        return Escalated;
    }

    @Override
    public String responsiblePerson() {
        return "Employee";
    }
},
Escalated {
    @Override
    public LeaveRequestState nextState() {
        return Approved;
    }

    @Override
    public String responsiblePerson() {
        return "Team Leader";
    }
},
Approved {
    @Override
    public LeaveRequestState nextState() {
        return this;
    }

    @Override
    public String responsiblePerson() {
        return "Department Manager";
    }
};

public abstract LeaveRequestState nextState(); 
public abstract String responsiblePerson();
LeaveRequestState state = LeaveRequestState.Submitted;

state = state.nextState();
assertEquals(LeaveRequestState.Escalated, state);

state = state.nextState();
assertEquals(LeaveRequestState.Approved, state);

state = state.nextState();
assertEquals(LeaveRequestState.Approved, state);