实战设计模式系列-State(状态)

时间:2022-06-05
本文章向大家介绍实战设计模式系列-State(状态),主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

【需求分析】

        state模式中,我们将状态逻辑和动作实现进行分离,当一个操作中要维护大量的case分支语句的时候,并且这些分支也都要依赖于对象的状态时,state模式将每一个分支都封装到独立的类中实现。不同的事物在不同的状态下会有不同的动作,在一个状态下又会转移到下一个状态。

        以TCP状态处理为例,TcpConnection只负责独立的业务逻辑,而TcpState负责业务逻辑转换和组合的业务逻辑,如TcpConnection会提供创建socket、监听接口,而TcpState业务从Close状态转换到Listen转换时,会调用TcpConnection类的创建socket和监听接口,这一点,也是通过在TcpConnection中声明TcpState为友元实例的。

        下面的例子给出了代码实例,在main函数中,只要接收到请求,直接调用HandleRequest即可,而不用关心当前的TCP连接状态。

【代码示例】

/* 
* state.h 
*//* 
* state.h 
*/  
#include <stdio.h>  
#include <stdlib.h>  
  
class TcpState;  
  
class TcpConnection  
{  
        public:  
                TcpConnection(TcpState* instance);  
                ~TcpConnection();  
  
        public:  
                void HandleRequest();  
                void ChangeState(TcpState* instance);  
  
        public:  
                void CreateSocket()  
                {  
                        printf("CreateSocket/n");  
                }  
  
                void BeginListen()  
                {  
                        printf("BeginListen/n");  
                }  
  
                void Accept()  
                {  
                        printf("Accept/n");  
                }  
  
                void Establish()  
                {  
                        printf("Establish/n");  
                }  
  
                void Close()  
                {  
                        printf("Close/n");  
                }  
  
  
        private:  
                friend class TcpState;  
                TcpState * m_instance;  
};  
  
class TcpState  
{  
        public:  
                virtual ~TcpState(){};  
  
        public:  
                virtual void Handle(TcpConnection* pTcpConnection){};  
};  
  
class TcpCloseState : public TcpState  
{  
        public:  
                void Handle(TcpConnection* pTcpConnection);  
};  
  
class TcpListenState : public TcpState  
{  
        public:  
                void Handle(TcpConnection* pTcpConnection);  
};  
  
class TcpEstablishState : public TcpState  
{  
        public:  
                void Handle(TcpConnection* pTcpConnection);  
};  
/* 
* state.cpp 
*/  
#include "state.h"  
  
TcpConnection::TcpConnection(TcpState* instance)  
{  
        m_instance = instance;  
}  
  
TcpConnection::~TcpConnection()  
{  
        delete m_instance;  
        m_instance = NULL;  
}  
void TcpConnection::HandleRequest()  
{  
        if (NULL == m_instance)  
        {  
                return;  
        }  
        m_instance->Handle(this);  
}  
  
void TcpConnection::ChangeState(TcpState* instance)  
{  
        m_instance = instance;  
}  
  
  
void TcpCloseState::Handle(TcpConnection* pTcpConnection)  
{  
        //create socket and begin listen  
        pTcpConnection->CreateSocket();  
        pTcpConnection->BeginListen();  
  
        //change state  
        pTcpConnection->ChangeState(new TcpListenState());  
}  
  
void TcpListenState::Handle(TcpConnection* pTcpConnection)  
{  
        //accpet and set establish  
        pTcpConnection->Accept();  
        pTcpConnection->Establish();  
  
        //change state  
        pTcpConnection->ChangeState(new TcpEstablishState());  
}  
  
void TcpEstablishState::Handle(TcpConnection* pTcpConnection)  
{  
        //close  
        pTcpConnection->Close();  
  
        //change state  
        pTcpConnection->ChangeState(new TcpCloseState());  
}  
  
int main(void)  
{  
        TcpState * pState= new TcpCloseState();  
        TcpConnection * pTcpConn = new TcpConnection(pState);  
        pTcpConn->HandleRequest();  
        pTcpConn->HandleRequest();  
        pTcpConn->HandleRequest();  
        delete pTcpConn;  
        return 0;  
} 

【执行结果】

root:/home/derrywang#g++ -o state state.cpp root:/home/derrywang#./state CreateSocket BeginListen Accept Establish Close