C++设计模式之状态模式(二)

2、智能空调的设计与实现

某软件公司将开发一套智能空调系统: 系统检测到温度处于20---30度之间,则切换到常温状态;温度处于30---45度,则切换到制冷状态; 温度小于20度,则切换到制热状态。请使用状态模式对此系统进行设计。

    从需求中可以看出,空调可以处于三种状态: 制热状态、常温状态、制冷状态。每种状态下都存在三种行为:保持常温、制冷、制热。

    空调抽象状态实现代码如下:

//空调抽象状态类
class AirConditionerState
{
public:	
	//保持常温
	virtual void KeepNormalTemperature(AirConditioner * pAirConditioner) = 0;

	//制冷
	virtual void refrigerate(AirConditioner * pAirConditioner) = 0;
	
	//制热
	virtual void Heat(AirConditioner * pAirConditioner) = 0;
};
    三种具体状态类声明如下:
//常温状态
class NormalTemperatureState : public AirConditionerState
{
public:	
	//保持常温
	void KeepNormalTemperature(AirConditioner * pAirConditioner);

	//制冷
	void refrigerate(AirConditioner * pAirConditioner);
	
	//制热
	void Heat(AirConditioner * pAirConditioner);
};



//制冷状态
class RefrigerateState : public AirConditionerState
{
public:	
	//保持常温
	void KeepNormalTemperature(AirConditioner * pAirConditioner);
	
	
	//制冷
	void refrigerate(AirConditioner * pAirConditioner);
	
	//制热
	void Heat(AirConditioner * pAirConditioner);
};




//制热状态
class HeatState : public AirConditionerState
{
public:	
	//保持常温
	void KeepNormalTemperature(AirConditioner * pAirConditioner);
	
	//制冷
	void refrigerate(AirConditioner * pAirConditioner);
	
	//制热
	void Heat(AirConditioner * pAirConditioner);
};
    每种状态下都存在保持常温、制冷、制热方法。这些方法带有一个AirConditioner类参数,方法内部使用这个参数回调空调的温度值,根据这个温度值,用于判断该方法如何实现,以及如何切换到其他状态。三种状态实现代码如下:
/******************************正常温度状态******************************************/

//保持常温
void NormalTemperatureState::KeepNormalTemperature(AirConditioner * pAirConditioner)
{

	int nTemperature = pAirConditioner->GetTemperature();

	if( nTemperature > 20 && nTemperature <= 30 )
	{
		cout << "已经是常温状态,不能调节为常温" << endl;
	}
}



//制冷
void NormalTemperatureState::refrigerate(AirConditioner * pAirConditioner)
{
	int nTemperature = pAirConditioner->GetTemperature();
	
	if( nTemperature > 30 && nTemperature <= 45 )
	{
		pAirConditioner->SetAirConditionerState(pAirConditioner->GetRefrigerateState());

		cout << "切换到制冷状态" << endl;
	}
}
	


//制热
void NormalTemperatureState::Heat(AirConditioner * pAirConditioner)
{
	int nTemperature = pAirConditioner->GetTemperature();
	
	if( nTemperature <= 20 )
	{
		pAirConditioner->SetAirConditionerState(pAirConditioner->GetHeatState());

		cout << "切换到制热状态" << endl;
	}
}



/******************************制冷状态******************************************/

//保持常温
void RefrigerateState::KeepNormalTemperature(AirConditioner * pAirConditioner)
{
	int nTemperature = pAirConditioner->GetTemperature();
	
	if( nTemperature > 20 && nTemperature <= 30 )
	{
		pAirConditioner->SetAirConditionerState(pAirConditioner->GetNormalTemperatureState());

		cout << "切换到常温状态" << endl;
	}
}
	


//制冷
void RefrigerateState::refrigerate(AirConditioner * pAirConditioner)
{
	int nTemperature = pAirConditioner->GetTemperature();
	
	if( nTemperature > 30 && nTemperature <= 45 )
	{
		cout << "已经是制冷状态,不能调节为制冷状态" << endl;
	}
}
	


//制热
void RefrigerateState::Heat(AirConditioner * pAirConditioner)
{
	int nTemperature = pAirConditioner->GetTemperature();
	
	if( nTemperature <= 20 )
	{
		pAirConditioner->SetAirConditionerState(pAirConditioner->GetHeatState());

		cout << "切换到制热状态" << endl;
	}
}



/******************************制热状态******************************************/


//保持常温
void HeatState::KeepNormalTemperature(AirConditioner * pAirConditioner)
{
	int nTemperature = pAirConditioner->GetTemperature();
	
	if( nTemperature > 20 && nTemperature <= 30 )
	{
		pAirConditioner->SetAirConditionerState(pAirConditioner->GetNormalTemperatureState());

		cout << "切换到常温状态" << endl;
	}
}
	
	

//制冷
void HeatState::refrigerate(AirConditioner * pAirConditioner)
{
	int nTemperature = pAirConditioner->GetTemperature();
	
	if( nTemperature > 30 && nTemperature <= 45 )
	{
		pAirConditioner->SetAirConditionerState(pAirConditioner->GetRefrigerateState());

		cout << "切换到制冷状态" << endl;
	}
}


	
//制热
void HeatState::Heat(AirConditioner * pAirConditioner)
{
	int nTemperature = pAirConditioner->GetTemperature();
	
	if( nTemperature <= 20 )
	{
		cout << "已经是制热状态,不能调节为制热状态" << endl;
	}
}
    空调类,也就是环境类Contex,维护了一个状态的引用,实现的时候将调用状态对象的方法。声明代码如下:
//空调类
class AirConditioner
{
private:
	//空调名称
	string m_strAirName;

	//空调当前温度
	int m_nTemperature;
	
	//常温状态
	AirConditionerState * m_pNormalTemperatureState;
	
	//制冷状态
	AirConditionerState * m_pRefrigerateState;

	//制热状态
	AirConditionerState * m_pHeatState;

	//当前温度状态
	AirConditionerState * m_pCurState;
public:
	//构造函数
	AirConditioner(string strAirName, int nTemperature);

	//虚构函数
	~AirConditioner();
	
	//调节温度
	void SetTemperature(int nTemperature);

	//获取温度
	int GetTemperature();

	//设置空调状态
	void SetAirConditionerState(AirConditionerState * pAirConditionerState);

	
	//获取常温状态
	AirConditionerState * GetNormalTemperatureState();

	//获取制冷状态
	AirConditionerState * GetRefrigerateState();

	//获取制热状态
	AirConditionerState * GetHeatState();


	//保持常温
	void KeepNormalTemperature();

	//制冷
	void refrigerate();

	//制热
	void Heat();
	
};
    空调类实现代码如下:
//构造函数
AirConditioner::AirConditioner(string strAirName, int nTemperature)
{
	m_strAirName = strAirName;
	m_nTemperature = nTemperature;

	m_pNormalTemperatureState = new NormalTemperatureState();
	m_pRefrigerateState = new RefrigerateState();
	m_pHeatState = new HeatState();

	m_pCurState = m_pNormalTemperatureState;
}



//虚构函数
AirConditioner::~AirConditioner()
{
	delete m_pNormalTemperatureState;
	m_pNormalTemperatureState = NULL;

	delete m_pRefrigerateState;
	m_pRefrigerateState = NULL;

	delete m_pHeatState;
	m_pHeatState = NULL;
}
	



//调节温度
void AirConditioner::SetTemperature(int nTemperature)
{
	m_nTemperature = nTemperature;
}



//获取温度
int AirConditioner::GetTemperature()
{
	return m_nTemperature;
}



//设置空调状态
void AirConditioner::SetAirConditionerState(AirConditionerState * pAirConditionerState)
{
	m_pCurState = pAirConditionerState;
}





//获取常温状态
AirConditionerState * AirConditioner::GetNormalTemperatureState()
{
	return m_pNormalTemperatureState;
}




//获取制冷状态
AirConditionerState * AirConditioner::GetRefrigerateState()
{
	return m_pRefrigerateState;
}




//获取制热状态
AirConditionerState * AirConditioner::GetHeatState()
{
	return m_pHeatState;
}





//保持常温
void AirConditioner::KeepNormalTemperature()
{
	m_pCurState->KeepNormalTemperature(this);
	
}




//制冷
void AirConditioner::refrigerate()
{
	m_pCurState->refrigerate(this);
}




//制热
void AirConditioner::Heat()
{
	m_pCurState->Heat(this);
}
    测试代码实现如下:
#include <iostream>
#include "AirConditioner.h"

using namespace std;

int main()
{

	AirConditioner * pAirConditioner = new AirConditioner("海尔空调", 25);

	/****************常温状态*************************/
	pAirConditioner->KeepNormalTemperature();

	cout << endl;
	
	/****************制冷状态*************************/
	pAirConditioner->SetTemperature(33);
	pAirConditioner->refrigerate();

	cout << endl;

	/****************制热状态*************************/
	pAirConditioner->SetTemperature(15);
	pAirConditioner->Heat();

	/****************销毁操作*************************/
	delete pAirConditioner;
	pAirConditioner = NULL;

	return 0;
}
    编译并执行,结果如下:


    将具体行为封装在常温状态、制冷状态、制热状态中。空调类(也就是环境类)维持一个当前状态的引用,当客户端调用环境类的方法时,将该调用操作委托给具体状态类。具体状态类实现该状态下的行为,以及控制切换到其他状态。客户端无需直接操作具体的状态类,而是由环境类代为处理,降低了客户端与具体状态类的耦合性。如果需要添加具体的状态类也很容易,只需要继承于抽象状态类并对环境类稍加修改就可以了。另外,也避免了大量if...else臃肿语句,把这些条件判断都封装成一个个状态类。



 


郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。