C++常用设计模式之:状态模式

状态模式是一种解决程序中条件判断问题的策略,当对象内部状态改变时,其行为也随之改变。在TCP操作的场景中,如Start、Connect、Stop等操作会改变TCP对象的状态,传统的if/else语句处理复杂,而状态模式通过对象自身切换状态简化了这一过程。通过UML结构图和伪码示例,展示了如何使用状态模式实现网络状态的动态切换,以实现更加灵活的代码结构。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

状态模式就是升级版的策略模式!它解决的也是程序中常见的条件可能变化的if/else或者switch/case语句,不同的是状态模式在状态发生改变时,其内部会使其指向下一种状态,无需调用者做出选择。这样解释好像还是太抽象了,算了,先看定义吧。

状态模式的定义:允许一个对象在其内部状态改变时改变它的行为。从而使对象看起来似乎修改了其行为。

看看上面的定义,是不是更抽象了...

还是用实际程序中例子来解释吧。我们在程序中会常常操作一个网络对象,比如一个TCP的操作,我们会调用诸如Start,Connect,Stop等等的操作,在进行完一个操作后,TCP对象的状态就会改变,这样下一次操作时我们会检测当前TCP对象是什么状态,然后再进行相应的操作。也是就是我们会根据当前TCP对象的状态来进行相应的操作。总之,要是按照正常的思路来写,就是一堆if/else。显然,如果这里的状态很多话,那写起来可就费劲了,搞不好就被自己绕晕了。这个时候就可以亮出状态模式了。

UML结构图如下:

下面我用伪码来表述上面的例子。

//先按照正常写代码的思路来写
//首先,我们有一堆状态,那肯定是枚举了
enum NetState {Net_Start,Net_Connect,Net_Stop};

//下面我们要进行操作了
class TCPProcess
{
protected:
      NetState  state;//状态对象
public:
      void Operation1() {
         if(state == Net_Start){
         //如果当前状态是....,就.........
         //操作完成后改变状态
           state = Net_Connect;
          }
         else if(state == Net_Connect){
         //如果当前状态是....,就.........
         //操作完成后改变状态
           state = Net_Stop;
          }
         else if(state == Net_Stop){
         //如果当前状态是....,就.........
         //操作完成后改变状态
           state = Net_Start;
          }
      }
      
      //下面类似,总之就是先判断当前状态,再操作,最后改变当前状态
      void  Operation2() {}
      void  Operation3() {}
};
//状态模式闪亮登场。。。
//首先,我们提炼一下这里稳定的部分,即稳定的接口有哪些,那显然是TCP操作本身了

//网络基类
class NetState
{
public:
    virtual ~NetState() {}
public:
    NetState *pNext;//下一种状态的指针
    virtual  void Operation1()=0;//不同状态下,可以进行什么样的操作
    virtual  void Operation2()=0;//不同状态下,可以进行什么样的操作
    virtual  void Operation3()=0;//不同状态下,可以进行什么样的操作
};

//如果是开始的状态
class StartState : public NetState
{
protected:
       static NetState *m_instance;
public:
       static NetState *getInstance(){
       if(m_instance ==  NULL){
         m_instance = new StartState();
         }
         return m_instance;
       }

       void Operation1()
      {        
        //...........
        pNext = StopState::getInstance();
      }
    
       void Operation2()
      {        
        //...........
        pNext = ConnectState::getInstance();
      }
    
       void Operation3()
      {        
        //............
        pNext = StartState::getInstance();
      }
};

//其它的状态类似
class StopState : public NetState {};
class ConnectState : public NetState {};

//下面我们要进行操作了
class TCPProcess
{
protected:
       NetState *m_pState;
public:
      TCPProcess(NetState *pState):m_pState(pState) {}

    void Operation1(){
        //...
        pState->Operation1();
        pState = pState->pNext;
        //...
    }
    
    void Operation2(){
        //...
        pState->Operation2();
        pState = pState->pNext;
        //...
    }
    
    void Operation3(){
        //...
        pState->Operation3();
        pState = pState->pNext;
        //...
    }

};

//现在看这段代码,和策略模式不同的就是我们在内部维护了一个指向下一种状态的指针而已

现在返回那张UML图我们再来看:

结合到我们的例子和状态模式的定义,其中稳定的部分就是我们的网络基类NetState和网络操作类TCPProcess。变化的就是各种各样的实际的网络状态。我们是通过组合的方式(TCPProcess类中包含一个NetState类的指针)实现的多态调用,并且在TCPProcess类中改变NetState类的状态

最后,如果理解的有偏差,还请指出

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值