狀態(tài)模型,就是當(dāng)一個(gè)對(duì)象的內(nèi)在狀態(tài)改變時(shí)允許改變其行為,這個(gè)對(duì)象看起來(lái)像是改變了其類。狀態(tài)模式主要解決的是當(dāng)控制一個(gè)對(duì)象狀態(tài)轉(zhuǎn)換的條件表達(dá)式過(guò)于復(fù)雜時(shí)的情況。把狀態(tài)的判斷邏輯轉(zhuǎn)移到表示不同狀態(tài)的一系列類當(dāng)中,可以把復(fù)雜的判斷邏輯簡(jiǎn)化。
狀態(tài)模型結(jié)構(gòu)圖
image
狀態(tài)模型基本代碼
#include <iostream>
using namespace std;
class Context;
class State { // 抽象狀態(tài)類,定義一個(gè)接口以封裝與Context的一個(gè)特定狀態(tài)相關(guān)的行為
public:
virtual void Handle(Context* c) = 0;
virtual ~State() {}
};
class Context { // 維護(hù)一個(gè)ConcreteState子類的實(shí)例,這個(gè)實(shí)例定義為當(dāng)前狀態(tài)
private:
State* state;
public:
Context(State* s) { state = s; }
void Request() { // // 對(duì)請(qǐng)求做處理,并設(shè)置下一狀態(tài)
if (state == NULL) return;
state->Handle(this);
}
void SetState(State* s) { state = s; }
virtual ~Context() {
if (state != NULL) {
delete state;
state = NULL;
}
}
};
// 具體狀態(tài)類,每一個(gè)字類實(shí)現(xiàn)與Context的一個(gè)狀態(tài)相關(guān)行為
class ConcreteStateA : public State {
public:
void Handle(Context* c);
};
class ConcreteStateB : public State {
public:
void Handle(Context* c);
};
class ConcreteStateC : public State {
public:
void Handle(Context* c);
};
void ConcreteStateA::Handle(Context* c) {
cout << "ConcreteStateA" << endl;
c->SetState(new ConcreteStateB());
}
void ConcreteStateB::Handle(Context* c) {
cout << "ConcreteStateB" << endl;
c->SetState(new ConcreteStateC());
}
void ConcreteStateC::Handle(Context* c) {
cout << "ConcreteStateC" << endl;
c->SetState(new ConcreteStateA());
}
int main() {
State* s = new ConcreteStateA();
Context* c = new Context(s);
c->Request(); // ConcreteStateA 切換狀態(tài)
c->Request(); // ConcreteStateB
c->Request(); // ConcreteStateC
delete s;
delete c;
return 0;
}
應(yīng)用場(chǎng)景
狀態(tài)模式通過(guò)把各種狀態(tài)轉(zhuǎn)換轉(zhuǎn)移邏輯分布到State的子類之間,來(lái)減少相互間的依賴。當(dāng)一個(gè)對(duì)象的行為取決于它的狀態(tài),并且它必須在運(yùn)行時(shí)根據(jù)狀態(tài)改變它的行為時(shí),就可以考慮使用狀態(tài)模式了。
優(yōu)點(diǎn):將與特定狀態(tài)有關(guān)的行為局部化,并且將不同狀態(tài)的行為分割開(kāi)來(lái)。