一. 舉例
一般汽車發動機工作時有四種狀態,吸氣、壓縮、做功和排氣。
在運行時,不同的狀態會有不同的行為,當前的狀態機器在適當的時候會過渡到下一狀態。
其實使用者在使用時根本不知道當前的狀態,也無需知道當前的狀態。使用者只需要給發動機一個初始狀態,最後得到一個停止狀態就行了。 結構圖如下:
代碼如下:
//狀態class State{public: virtual void Operation(Work *work) {}};//工作class Work{private: State *m_state; //目前狀態 int m_step; //步驟 public: Work(State *state): m_state(state), m_step(0) {} ~Work() { delete m_state; } int GetStep() { return m_step; } void SetStep(int step) { m_step = step; } void SetState(State *state) { delete m_state; m_state = state; } void Operation() { m_state->Operation(this); }};//排氣狀態class ExhaustState: public State { public: void Operation(Work *work) //排氣操作 { if(work->GetStep() == 4) { cout<<"Step : "<<work->GetStep()<<"排氣操作"<<endl; } }};//做功狀態class ActState: public State{public: void Operation(Work *work) //做功操作 { if(work->GetStep() == 3) { cout<<"Step : "<<work->GetStep()<<"做功操作"<<endl; } else { work->SetState(new ExhaustState()); work->Operation(); } }}; //壓縮狀態class CompressState: public State {public: void Operation(Work *work) //壓縮操作 { if(work->GetStep() == 2) { cout<<"Step : "<<work->GetStep()<<"壓縮操作"<<endl; } else { work->SetState(new ActState()); work->Operation(); } }};//吸氣狀態class InhaleState: public State{public: void Operation(Work *work) //吸氣操作 { if(work->GetStep() == 1) { cout<<"Step : "<<work->GetStep()<<"吸氣操作"<<endl; } else { State *p = new CompressState(); work->SetState(p); work->Operation(); } }};//測試代碼int main() { State* st = new InhaleState(); //初始狀態 Work *work = new Work(st); for(int i = 1; i < 5; ++i) { work->SetStep(i); work->Operation(); //操作 } delete work; return 0;}
二. 狀態模式
定義:允許一個對象在其內部狀態改變時改變它的行為。對象看起來似乎修改了它的類。 結構圖:
使用範圍:
(1)一個對象的行為取決於它的狀態, 並且它必須在運行時刻根據狀態改變它的行為。(上面的例子就是這種情況)
(2)一個操作中含有龐大的多分支的條件陳述式,且這些分支依賴於該對象的狀態。