狀態模式是根據其狀態變化來改變對象的行為,允許對象根據內部狀態來實現不同的行為。內容類可以具有大量的內部狀態,每當調用實現時,就委托給狀態類進行處理。 作用 當一個對象的內在狀態改變時允許改變其行為,這個對象看起來像是改變了其類。狀態模式主要解決的是當控制一個對象狀態的條件表達式過於複雜時的情況。把 ...
狀態模式是根據其狀態變化來改變對象的行為,允許對象根據內部狀態來實現不同的行為。內容類可以具有大量的內部狀態,每當調用實現時,就委托給狀態類進行處理。
作用
當一個對象的內在狀態改變時允許改變其行為,這個對象看起來像是改變了其類。狀態模式主要解決的是當控制一個對象狀態的條件表達式過於複雜時的情況。把狀態的判斷邏輯轉移到表示不同狀態的一系列類中,可以把複雜的判斷邏輯簡化。
類視圖
實現
class State;
class LowState; //低等折扣
class MediaState; //中等折扣
class HighState; //高等折扣
//折扣
class Discount
{
public:
Discount(State* sta):m_state(sta){}
~Discount(){delete State;}
void request(){ m_state->handle(this);}
void setstate(State* sta)
{
delete m_state;
m_state = sta;
}
int GetBuyNum(){return m_nBuyNum;}
void SetBuyNum(int nNum){m_nBuyNum =nNum; }
private:
State* m_state;
int m_nBuyNum;
};
//運行系統
class State
{
public:
virtual void handle(Discount*)=0;
};
class LowState : public State
{
public:
LowState();
~ LowState();
void handle(Discount* pDis)
{
if (pDis)
{
int nNum = pDis->GetBuyNum();
if (nNum<=10)
{
cout<< "打9折";
}
else
{
pDis->setstate(new MediaState());
pDis->request();
}
}
}
};
class MediaState : public State
{
public:
MediaState();
~ MediaState();
void handle(Discount* pDis)
{
if (pDis)
{
int nNum = pDis->GetBuyNum();
if(nNum<=10)
{
pDis->setstate(new LowState());
pDis->getstate();
}
else if (nNum>10 && nNum <=50)
{
cout<< "打7折";
}
else
{
pDis->setstate(new HighState());
pDis->request();
}
}
}
};
class HighState : public State
{
public:
void handle(Discount* pDis)
{
if (pDis)
{
int nNum = pDis->GetBuyNum();
if (nNum>50)
{
cout<< "打5折";
}
else
{
pDis->setstate(new MediaState());
pDis->request();
}
}
}
};
int main()
{
Discount disc(new LowState());
disc.SetBuyNum(40);
disc.request();
}
狀態模式里可以看到策略模式和責任鏈模式的影子,從結構和功能上會有些相似;
策略模式和狀態模式最為相像,其二者主要區別是策略模式更關心的是strategy的類型多態實現,一般會在==外部調用==時進行指明;而狀態模式不會直接決定State的具體實現,而是通過==內部狀態==參數來決定。
責任鏈模式由前後的鏈條關係,在創建時需要明確指出,而狀態模式是由==狀態==選擇其多態的實現。
所以狀態模式之所以單獨獨立出來,就是為了凸顯在==不同狀態下的不同實現==。
這篇電梯的實現很形象,大家可以參考電梯應用
應用場景
- 一個對象的行為取決於它的狀態,並且它必須在運行時刻根據狀態改變它的行為。
- 一個操作中含有龐大的多分支結構,並且這些分支決定於對象的狀態。