【需求分析】
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