首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

設計模式實作系列(十七):State 狀態模式 - 將狀態相關行為封裝為獨立類別

     編輯:關於C++

模式意圖

允許一個物件在其內部狀態改變時改變它的行為。物件看起來好像修改了它的類別。

UML 結構圖

State Pattern UML

核心解析:替換龐大的 switch-case

傳統做法在 Context 中用 switch(state) 分派行為,導致:

  • 單一類別膨脹,違反單一職責原則。
  • 新增狀態需修改現有程式碼,違反開放封閉原則。
  • 狀態轉移邏輯分散在各 case 中,難以維護。

State 模式將每種狀態封裝為獨立類別(ConcreteState),Context 委派給當前狀態物件處理請求,並由狀態物件負責轉移至下一狀態。

C++ 完整實作

1. State.h

#ifndef STATE_H
#define STATE_H

class State;
class Context;

class Context {
public:
    Context(State* pState);
    ~Context();
    void Request();
    void ChangeState(State* pState);
private:
    State* m_pState;
};

class State {
public:
    virtual ~State() {}
    virtual void Handle(Context* pContext) = 0;
};

class ConcreteStateA : public State {
public:
    void Handle(Context* pContext);
};

class ConcreteStateB : public State {
public:
    void Handle(Context* pContext);
};

#endif

2. State.cpp

#include "State.h"
#include <iostream>

Context::Context(State* pState) : m_pState(pState) {}
Context::~Context() { delete m_pState; m_pState = nullptr; }

void Context::Request() {
    if (m_pState) m_pState->Handle(this);
}

void Context::ChangeState(State* pState) {
    if (m_pState) { delete m_pState; m_pState = nullptr; }
    m_pState = pState;
}

void ConcreteStateA::Handle(Context* pContext) {
    std::cout << "Handle by ConcreteStateA\n";
    if (pContext) pContext->ChangeState(new ConcreteStateB()); // 切換狀態
}

void ConcreteStateB::Handle(Context* pContext) {
    std::cout << "Handle by ConcreteStateB\n";
    if (pContext) pContext->ChangeState(new ConcreteStateA()); // 切換回 A
}

3. Main.cpp

#include "State.h"

int main() {
    State* pState = new ConcreteStateA();
    Context* pContext = new Context(pState);
    pContext->Request(); // Handle by ConcreteStateA -> 切換到 B
    pContext->Request(); // Handle by ConcreteStateB -> 切換到 A
    pContext->Request(); // Handle by ConcreteStateA
    delete pContext;
    return 0;
}

State vs Strategy 模式辨析

維度State 模式Strategy 模式
封裝對象狀態相關行為演算法/策略
狀態轉移由狀態物件內部主動發起由客戶端/Context 顯式設定
適用場景物件行為隨內部狀態頻繁變化(如 TCP 連線狀態、遊戲角色狀態)需在執行期動態切換演算法(如排序、壓縮、路徑規劃)
結構相似度極高(均為委派給抽象介面)極高

適用場景

  • 物件行為受狀態影響大,且狀態轉移頻繁、邏輯複雜。
  • 工作流引擎、通訊協定狀態機、遊戲 AI 狀態(巡邏/追擊/逃跑)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved