1. 意圖
允許對象在內部狀態改變時改變其行為,對象看起來似乎修改了它的類。
2. 別名
Objects for States
3. 動機
TCP 連接對象在不同狀態(Established、Listening、Closed)下對同一請求(如 Open)有不同反應。若用大量 if/else 判斷狀態,代碼臃腫且難維護。State 模式將每種狀態封裝為獨立類,上下文對象委派給當前狀態對象。
4. 適用性
- 對象行為取決於狀態,且需在運行時根據狀態改變行為。
- 操作中含大量依賴狀態的條件分支,且多操作結構相同。
5. 結構角色
| 角色 | 職責 |
| Context(環境) | 持有當前狀態引用,定義客戶端接口,委派請求給狀態對象。 |
| State(抽象狀態) | 定義封裝特定狀態行為的接口。 |
| ConcreteState(具體狀態) | 實現特定狀態對應的行為。 |
6. 代碼示例(Java)
// 抽象狀態
interface State {
void handle(Context ctx);
}
// 具體狀態 A
class StateA implements State {
public void handle(Context ctx) {
System.out.println("StateA: 執行操作1");
ctx.setState(new StateB()); // 狀態轉換
}
}
// 具體狀態 B
class StateB implements State {
public void handle(Context ctx) {
System.out.println("StateB: 執行操作2");
ctx.setState(new StateA());
}
}
// 環境
class Context {
private State state;
public Context(State s) { state = s; }
public void setState(State s) { state = s; }
public void request() { state.handle(this); }
}
// 測試
public class Test {
public static void main(String[] args) {
Context ctx = new Context(new StateA());
ctx.request(); // StateA
ctx.request(); // StateB
ctx.request(); // StateA
}
}
輸出
StateA: 執行操作1
StateB: 執行操作2
StateA: 執行操作1
7. 相關模式
- Flyweight:解釋何時共享狀態對象(通常狀態對象是單例)。
- Singleton:具體狀態類常實現為單例。
8. 實戰場景
- 工作流引擎:訂單狀態(創建、支付、發貨、完成、取消)。
- 遊戲角色:待機、行走、攻擊、受傷、死亡。
- 網絡協議:TCP 狀態機、HTTP 解析狀態。
- UI 控件:按鈕(正常、懸停、按下、禁用)。
9. 優缺點
| 優點 | 缺點 |
| 消除大量條件分支,符合開閉原則 | 增加類數量,小項目可能過度設計 |
| 狀態轉換顯式化,易維護 | 狀態間可能產生循環依賴 |
| 可共享狀態對象(Flyweight) | 需仔細設計狀態邊界 |
- 上一篇文章: 行為型設計模式:Memento(備忘錄)模式完整指南
- 下一篇文章: LeetCode 45:Jump Game II —— 貪心算法優化詳解
Copyright ©
程式碼之家 All Rights Reserved