第十一章 状态模式

1. 状态切换的逻辑

1.1 状态机的C实现

可以参考如下一个C的状态切换实现,了解何为状态机
https://www.cnblogs.com/lihuidashen/p/11510532.html

笔者这里抽取其核心设计

/*有限状态以及有限事件*/
typedef enum{
  event_1=1,
  event_2,
  event_3,
  event_4,
  event_5}EventID;
  
  typedef enum {
  state_1=1,
  state_2,
  state_3}
State;
/*任意设定的状态机1*/
StateTransform stateTran1[] = {
    {state_1,event_3,state_2,f121},
    {state_1,event_4,state_2,NULL},
    {state_2,event_1,state_3,f231},
    {state_2,event_4,state_2,f221},
    {state_3,event_2,state_1,f311},
    {state_3,event_3,state_2,f321},
    {state_3,event_5,state_3,f331}
};

/*任意设定的状态机2*/
StateTransform stateTran2[] = {
    {state_1,event_3,state_2,f121},
    {state_1,event_4,state_2,NULL},
    {state_1,event_2,state_3,f131},/*add entry*/
    {state_1,event_1,state_3,f131},/*add entry*/
    {state_2,event_1,state_3,f231},
    {state_2,event_4,state_2,f221},
    {state_3,event_2,state_1,f311},
    {state_3,event_3,state_2,f321},
    {state_3,event_5,state_3,f331}
};

1.2 最糟糕的设计

如果我们舍弃1.1的实现,就会陷入最糟糕的设计方案
这样的代码给人什么感觉?烂!

/*
take this table for example
StateTransform stateTran1[] = {
    {state_1,event_3,state_2,f121},
    {state_1,event_4,state_2,NULL},
    {state_2,event_1,state_3,f231},
    {state_2,event_4,state_2,f221},
    {state_3,event_2,state_1,f311},
    {state_3,event_3,state_2,f321},
    {state_3,event_5,state_3,f331}
};

*/
enum State curState;
enum EventID curEvt;
...
if(curState == state_1)
{
	if(curEvt == event_3)
	curEvt = state_2;f121(curEvt);
	else if (curEvt == event_4 );
	curEvt = state_2;
}
else if (curState == state_2)
{
	if(curEvt == event_1)
	curEvt = state_3;f231(curEvt);
	else if (curEvt == event_4 );
	curEvt = state_2;f221(curEvt);	
}
else if (curState == state_3)
{
	if(curEvt == event_2)
	curEvt = state_1;f311(curEvt);
	else if (curEvt == event_3 );
	curEvt = state_2;f321(cur![在这里插入图片描述](https://img-blog.csdnimg.cn/9e11f539a00d4f71a19ea51372442f15.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASm9oaG55IFJhZGU=,size_20,color_FFFFFF,t_70,g_se,x_16)
Evt);	
	else if (curEvt == event_5 );
	curEvt = state_3;f331(curEvt);
}

2. C++实现的状态机

2.1 状态机设计模板

在这里插入图片描述

2.2 状态机模式实现代码

/******************************************************************************

                              Online C++ Compiler.
               Code, Compile, Run and Debug C++ program online.
Write your code in this editor and press "Run" button to compile and execute it.

*******************************************************************************/
/*
take this table for example

StateTransform stateTran1[] = {
    {state_1,event_3,state_2,f121},
    {state_1,event_4,state_2,NULL},
    {state_2,event_1,state_3,f231},
    {state_2,event_4,state_2,f221},
    {state_3,event_2,state_1,f311},
    {state_3,event_3,state_2,f321},
    {state_3,event_5,state_3,f331}
*/
#include <iostream>

using namespace std;

/*State interface declaration*/
class State
{
  public:
  virtual void Event_1(void){}
  virtual void Event_2(void){}
  virtual void Event_3(void){}
  virtual void Event_4(void){}
  virtual void Event_5(void){}
};


/*Concrete States declaration*/
class StateMachine;
class State1:public State
{
public:
  State1(StateMachine* statemachine);
  void Event_3(void);
  void Event_4(void);
private:
StateMachine* m_statemachine;
};

class State2:public State
{
public:
  State2(StateMachine* statemachine);
  void Event_1(void);
  void Event_4(void);
private:
StateMachine* m_statemachine;
};

class State3:public State
{
public:
  State3(StateMachine* statemachine);
  void Event_2(void);
  void Event_3(void);
  void Event_5(void);
private:
StateMachine* m_statemachine;
};

/*StateMachine declaration*/
class StateMachine
{
  public:
  StateMachine(void);
  ~StateMachine(void);
  void setState(State* state);
  State* getState(void);
  State1* m_state1;
  State2* m_state2;
  State3* m_state3;
  State* m_curState;
};

/*Concrete States*/
State1::State1(StateMachine* statemachine)
{
    m_statemachine = statemachine;
}
void State1::Event_3(void)
{
    cout << "evt3@state1->Action Event_3 -> state2" << endl;
    m_statemachine->setState(m_statemachine->m_state2);
}
void State1::Event_4(void)
{
    cout << "evt4@state1->Action Event_4 -> state2" << endl;
    m_statemachine->setState(m_statemachine->m_state2);
}

State2::State2(StateMachine* statemachine)
{
    m_statemachine = statemachine;
}
void State2::Event_1(void)
{
    cout << "evt3@state2->Action Event_1 -> state3" << endl;
    m_statemachine->setState(m_statemachine->m_state3);
}
void State2::Event_4(void)
{
    cout << "evt4@state2->Action Event_4 -> state2" << endl;
    m_statemachine->setState(m_statemachine->m_state2);
}

State3::State3(StateMachine* statemachine)
{
    m_statemachine = statemachine;
}
void State3::Event_2(void)
{
    cout << "evt2@state3->Action Event_2 -> state1" << endl;
    m_statemachine->setState(m_statemachine->m_state1);
}
void State3::Event_3(void)
{
    cout << "evt3@state3->Action Event_3 -> state2" << endl;
    m_statemachine->setState(m_statemachine->m_state2);
}
void State3::Event_5(void)
{
    cout << "evt5@state3->Action Event_5 -> state3" << endl;
    m_statemachine->setState(m_statemachine->m_state3);
}


/*state Machine*/
StateMachine::StateMachine(void)
{
    m_state1 = new State1(this);
    m_state2 = new State2(this);
    m_state3 = new State3(this);
    
    m_curState = NULL;
}
StateMachine::~StateMachine(void)
{
    delete m_state1;
    delete m_state2;    
    delete m_state3;
    
}
State* StateMachine::getState(void)
{
    return m_curState;
}

void StateMachine::setState(State* state)
{
    m_curState = state;
}



int main()
{
    StateMachine* stateMachine = new StateMachine();
    
    /*starts from state1*/
    stateMachine->setState(stateMachine->m_state1);
    auto state = stateMachine->getState();
    state->Event_3();
    
    stateMachine->setState(stateMachine->m_state1);
    state = stateMachine->getState();
    state->Event_4();
    
    /*starts from state2*/
    stateMachine->setState(stateMachine->m_state2);
    state = stateMachine->getState();
    state->Event_1();
    
    stateMachine->setState(stateMachine->m_state2);
    state = stateMachine->getState();
    state->Event_4(); 
    
    /*starts from state3*/
    stateMachine->setState(stateMachine->m_state3);
    state = stateMachine->getState();
    state->Event_2(); 
    
    stateMachine->setState(stateMachine->m_state3);
    state = stateMachine->getState();
    state->Event_3(); 
    
    stateMachine->setState(stateMachine->m_state3);
    state = stateMachine->getState();
    state->Event_5();   
    
    delete stateMachine;
    return 0;
}

输出:
evt3@state1->Action Event_3 -> state2
evt4@state1->Action Event_4 -> state2
evt3@state2->Action Event_1 -> state3
evt4@state2->Action Event_4 -> state2
evt2@state3->Action Event_2 -> state1
evt3@state3->Action Event_3 -> state2
evt5@state3->Action Event_5 -> state3

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值