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臃肿语句,把这些条件判断都封装成一个个状态类。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。