状态机设计

State Machine Designing

本文关键字:状态机      更新时间:2023-10-16

我正在使用c++中的协议设计代码,需要有关状态机设计的帮助。

我们拥有的所有状态机都具有相同的性质。每个状态机都有特定的状态(S1、S2等),每个状态只能接受特定类型的事件(E1、E2等)。根据事件处理的结果,机器进入下一个状态。

例如,从状态S1到事件E1,机器可以移动到S2或S3。我研究了状态设计模式,但它建议所有状态(派生状态类)都应该实现状态机可以执行的所有操作,或者基本状态类应该实现这些操作。在我的情况下,单个状态只能处理某些事件,所以我认为状态设计模式不适用。

你能提出实现这种机器的最佳方式/模式吗。

根据"四人帮",当对象的行为取决于其状态,并且必须在运行时根据该状态更改行为时,状态设计模式适用

根据事件更改状态的状态机的描述似乎与此描述相匹配。

class StateMachine {    // state machine that processes events received
    State *s; 
public:  
    StateMachine();         // constructor: here you shall set initial state
    void process (Event* e); // processes the event and sets the next state
    bool isReady ();        // example of other requests
};

这个模式的原理是有一个抽象基类,定义StateMachine可能委托给一个状态的所有潜在的依赖于状态的"操作"。

class State {
public: 
      virtual void process (StateMachine *m, Event* e)=0;    // called by state machine /  pure virtual MUST be implemented in concrete state 
      virtual bool isReady(StateMachine *m);  // example  
      ...                               // other "actions"     
};

然后,您的状态和状态机之间的接口将很容易定义。例如:

void StateMachine::Process (Event *e) {
     s->Process (this, e);   // calls the Process() of the current state 
}

衍生的具体状态应实施不同的行为。由于此*模式适用于C++中的虚拟函数,因此必须为每个具体状态定义所有操作(在基类或派生状态中)。这是定义虚拟函数的直接结果。

但对于不适用于所有状态的操作,您可能会有一个默认操作,要么什么都不做,要么触发错误(错误消息、异常…)。这取决于您的总体设计,是否防止此类情况发生。

例如:

bool State::isReady(StateMachine *m) {  // if this request is only relevant for a couple of states
   throw std::exception ("unauthorized request");   // trigger an exception if it happens
   return false;
}    // this is done by default, except for concrete state that defines somtehing else 

根据你的描述,我真的会选择州模式。