C++設計模式之狀態模式(二)
阿新 • • 發佈:2017-05-21
virtual alt 虛構函數 需求 rate names clas term delete
三種詳細狀態類聲明例如以下: 每種狀態下都存在保持常溫、制冷、制熱方法。這些方法帶有一個AirConditioner類參數,方法內部使用這個參數回調空調的溫度值,依據這個溫度值。用於推斷該方法怎樣實現。以及怎樣切換到其它狀態。三種狀態實現代碼例如以下:
空調類。也就是環境類Contex,維護了一個狀態的引用,實現的時候將調用狀態對象的方法。聲明代碼例如以下:
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); };
/******************************正常溫度狀態******************************************/ //保持常溫 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; } }
//空調類 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; }編譯並運行,結果例如以下:
將詳細行為封裝在常溫狀態、制冷狀態、制熱狀態中。
空調類(也就是環境類)維持一個當前狀態的引用,當client調用環境類的方法時,將該調用操作托付給詳細狀態類。詳細狀態類實現該狀態下的行為,以及控制切換到其它狀態。client無需直接操作詳細的狀態類,而是由環境類代為處理。減少了client與詳細狀態類的耦合性。假設須要加入詳細的狀態類也非常easy,僅僅須要繼承於抽象狀態類並對環境類稍加改動就能夠了。另外。也避免了大量if...else臃腫語句。把這些條件推斷都封裝成一個個狀態類。
C++設計模式之狀態模式(二)