最近项目中需要实现一个主备切换的功能,通过分析可以得出也就两个状态的切换,使用if/switch之类的语句可以轻松搞定,但是为了学习并实践State模式,这里采取了一个State模式的实现:
// HAState.h: interface for the HAState class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_HASTATE_H__410262B3_3FEB_44B3_BFA7_04C4BEBCE636__INCLUDED_)
#define AFX_HASTATE_H__410262B3_3FEB_44B3_BFA7_04C4BEBCE636__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <iostream>
class HASwitch;
enum HASTATE
{
STANDBY,
PRIMARY,
FAILURE
};
class HAState
{
public:
HAState();
virtual ~HAState();
virtual HASTATE getState();
virtual bool standby2primary( HASwitch* pSwitch ) = 0;
virtual bool primary2standby( HASwitch* pSwitch ) = 0;
protected:
void changeState( HASwitch pSwitch, HAState pNewState );
protected:
HASTATE m_euState;
};
#endif // !defined(AFX_HASTATE_H__410262B3_3FEB_44B3_BFA7_04C4BEBCE636__INCLUDED_)
// HAState.cpp: implementation of the HAState class.
//
//////////////////////////////////////////////////////////////////////
#include “HAState.h”
#include “HASwitch.h”
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
HAState::HAState():m_euState( FAILURE )
{
std::cout << “Call “ << FUNCTION << std::endl;
}
HAState::~HAState()
{
std::cout << “Call “ << FUNCTION << std::endl;
}
void HAState::changeState( HASwitch pSwitch, HAState pNewState )
{
std::cout << “Call “ << FUNCTION << std::endl;
pSwitch->changeState( pNewState );
}
HASTATE HAState::getState()
{
std::cout << “Call “ << FUNCTION << std::endl;
return m_euState;
}
// PrimaryState.h: interface for the PrimaryState class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_PRIMARYSTATE_H__DFA509B1_9344_4750_A582_5637A65DF2A8__INCLUDED_)
#define AFX_PRIMARYSTATE_H__DFA509B1_9344_4750_A582_5637A65DF2A8__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <boost/noncopyable.hpp>
#include “HAState.h”
class PrimaryState : public HAState, public boost::noncopyable
{
public:
PrimaryState();
virtual ~PrimaryState();
static PrimaryState& instance();
virtual bool standby2primary( HASwitch pSwitch ) ;
virtual bool primary2standby( HASwitch pSwitch ) ;
private:
static PrimaryState s_Instance;
};
#endif // !defined(AFX_PRIMARYSTATE_H__DFA509B1_9344_4750_A582_5637A65DF2A8__INCLUDED_)
// PrimaryState.cpp: implementation of the PrimaryState class.
//
//////////////////////////////////////////////////////////////////////
#include “PrimaryState.h”
#include “StandbyState.h”
#include “HASwitch.h”
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
PrimaryState PrimaryState::s_Instance;
PrimaryState::PrimaryState()
{
std::cout << “Call “ << FUNCTION << std::endl;
m_euState = PRIMARY;
}
PrimaryState::~PrimaryState()
{
std::cout << “Call “ << FUNCTION << std::endl;
}
bool PrimaryState::standby2primary( HASwitch* pSwitch )
{
std::cout << “Call “ << FUNCTION << std::endl;
std::cout << “Current state is already primary” << std::endl;
return true;
}
bool PrimaryState::primary2standby( HASwitch* pSwitch )
{
std::cout << “Call “ << FUNCTION << std::endl;
std::cout << “Begin switch to standby…” << std::endl;
std::cout << "Do something" << std::endl;
changeState( pSwitch, &StandbyState::instance() );
std::cout << "End switch to standby..." << std::endl;
return true;
}
PrimaryState& PrimaryState::instance()
{
std::cout << “Call “ << FUNCTION << std::endl;
return s_Instance;
}
// StandbyState.h: interface for the StandbyState class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_STANDBYSTATE_H__028C47F8_1A92_4854_A93D_2AECB6A17DF6__INCLUDED_)
#define AFX_STANDBYSTATE_H__028C47F8_1A92_4854_A93D_2AECB6A17DF6__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <boost/noncopyable.hpp>
#include “HAState.h”
class StandbyState : public HAState, public boost::noncopyable
{
public:
StandbyState();
virtual ~StandbyState();
static StandbyState& instance();
virtual bool standby2primary( HASwitch pSwitch ) ;
virtual bool primary2standby( HASwitch pSwitch ) ;
private:
static StandbyState s_Instance;
};
#endif // !defined(AFX_STANDBYSTATE_H__028C47F8_1A92_4854_A93D_2AECB6A17DF6__INCLUDED_)
// StandbyState.cpp: implementation of the StandbyState class.
//
//////////////////////////////////////////////////////////////////////
#include “StandbyState.h”
#include “PrimaryState.h”
#include “HASwitch.h”
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
StandbyState StandbyState::s_Instance;
StandbyState::StandbyState()
{
std::cout << “Call “ << FUNCTION << std::endl;
m_euState = STANDBY;
}
StandbyState::~StandbyState()
{
std::cout << “Call “ << FUNCTION << std::endl;
}
bool StandbyState::standby2primary( HASwitch* pSwitch )
{
std::cout << “Call “ << FUNCTION << std::endl;
std::cout << “Begin switch to primary…” << std::endl;
std::cout << "Do something" << std::endl;
changeState( pSwitch, &PrimaryState::instance() );
std::cout << "End switch to primary..." << std::endl;
return true;
}
bool StandbyState::primary2standby( HASwitch* pSwitch )
{
std::cout << “Call “ << FUNCTION << std::endl;
std::cout << “Current state is already standby” << std::endl;
return true;
}
StandbyState& StandbyState::instance()
{
std::cout << “Call “ << FUNCTION << std::endl;
return s_Instance;
}
// HASwitch.h: interface for the HASwitch class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_HASWITCH_H__AC109E28_51E4_46AE_BC07_9E93FA747B65__INCLUDED_)
#define AFX_HASWITCH_H__AC109E28_51E4_46AE_BC07_9E93FA747B65__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <boost/noncopyable.hpp>
#include “HAState.h”
class HASwitch : public boost::noncopyable
{
friend class HAState;
public:
HASwitch();
virtual ~HASwitch();
static HASwitch& instance();
HASTATE getState() const;
boolstandby2primary();
boolprimary2standby();
private:
void changeState( HAState pNewState );
private:
static HASwitch g_Instance;
HAState m_pCurState;
};
#endif // !defined(AFX_HASWITCH_H__AC109E28_51E4_46AE_BC07_9E93FA747B65__INCLUDED_)
// HASwitch.cpp: implementation of the HASwitch class.
//
//////////////////////////////////////////////////////////////////////
#include “HASwitch.h”
#include “HAState.h”
#include “PrimaryState.h”
#include “StandbyState.h”
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
HASwitch HASwitch::g_Instance;
HASwitch::HASwitch()
{
m_pCurState = &StandbyState::instance();
std::cout << “Call “ << FUNCTION << std::endl;
}
HASwitch::~HASwitch()
{
std::cout << “Call “ << FUNCTION << std::endl;
}
HASTATE HASwitch::getState() const
{
std::cout << “Call “ << FUNCTION << std::endl;
return m_pCurState->getState();
}
bool HASwitch::standby2primary()
{
std::cout << “Call “ << FUNCTION << std::endl;
return m_pCurState->standby2primary(this);
}
bool HASwitch::primary2standby()
{
std::cout << “Call “ << FUNCTION << std::endl;
return m_pCurState->primary2standby(this);
}
void HASwitch::changeState( HAState* pNewState )
{
std::cout << “Call “ << FUNCTION << std::endl;
m_pCurState = pNewState;
}
HASwitch& HASwitch::instance()
{
return g_Instance;
}
测试代码:
#include <iostream>
#include <assert.h>
#include “HASwitch.h”
int main(int argc , char ** argv)
{
assert( HASwitch::instance().getState() == STANDBY );
HASwitch::instance().standby2primary();
assert( HASwitch::instance().getState() == PRIMARY );
HASwitch::instance().primary2standby();
assert( HASwitch::instance().getState() == STANDBY );
return 0;
}