狀態模式允許物件在內部狀態改變時改變其行為,物件彷彿修改了自己的類別。本文對比傳統 switch-case 寫法,詳解狀態模式結構、協作流程、適用場景與完整程式碼實作。
typedef enum { state, state1, state2 } State;
void Action(State actionState) {
if (actionState == state) { /* ... */ }
else if (actionState == state1) { /* ... */ }
else if (actionState == state2) { /* ... */ }
}
新增狀態需修改原函數,違反開閉原則,測試困難,分支膨脹難以維護。

#include <iostream>
using namespace std;
class Context; // 前向宣告
class State {
public:
virtual void Handle(Context *pContext) = 0;
virtual ~State() {}
};
class ConcreteStateA : public State {
public:
void Handle(Context *pContext) override {
cout << "I am ConcreteStateA." << endl;
}
};
class ConcreteStateB : public State {
public:
void Handle(Context *pContext) override {
cout << "I am ConcreteStateB." << endl;
}
};
class Context {
State *m_pState;
public:
Context(State *pState) : m_pState(pState) {}
void Request() { if (m_pState) m_pState->Handle(this); }
void ChangeState(State *pState) { m_pState = pState; }
~Context() { delete m_pState; }
};
int main() {
State *pStateA = new ConcreteStateA();
State *pStateB = new ConcreteStateB();
Context *pContext = new Context(pStateA);
pContext->Request(); // 輸出: I am ConcreteStateA.
pContext->ChangeState(pStateB);
pContext->Request(); // 輸出: I am ConcreteStateB.
delete pContext;
}
| 維度 | 狀態模式 | 策略模式 |
|---|---|---|
| 核心關注 | 狀態轉換與狀態相關行為 | 同一動作的不同演算法實作 |
| 狀態/策略持有者 | Context 內部管理狀態轉換 | 客戶端決定使用哪個策略 |
| 典型場景 | 訂單流程、遊戲角色狀態、TCP 連線狀態 | 排序演算法、支付方式、壓縮格式 |
狀態模式將條件分支分散到各狀態類別,消除巨大 switch-case,使狀態轉換明確、易擴展、易測試。適用於多狀態、狀態轉換複雜的系統核心邏輯。