C++設計模式--狀態模式

狀態模式(State Pattern)

定義

在不破壞封裝性的前提下,捕獲一個對象的內部狀態,並在該對象之外保存這個狀態。這樣以後就可以將該對象恢復到原先的狀態       

                     

  • State類,抽象狀態類,定義一個接口以封裝與Context的一個特定狀態相關的行爲。
  • ConcreteState類,具體狀態,每一個子類實現一個與Context的一個狀態相關的行爲。
  • Context類,維護一個ConcreteState子類的實例,這個實例定義當前的狀態。

常用場景

  • 一個對象的行爲取決於它的狀態,並且它必須在運行時刻根據狀態改變它的行爲;
  • 一個操作中含有龐大的多分支的條件語句,且這些分支依賴於該對象的狀態。這個狀態通常用一個或多個枚舉常量表示。通常,有多個操作包含這一相同的條件結構。State 模式將每一個條件分支放入一個獨立的類中。這使得你可以根據自身情況將對象的狀態作爲一個對象,這一對象可以不依賴於其他對象而獨立變化。
     

優缺點

優點:

  • 將與特定狀態相關的行爲局部化,並且將不同狀態的行爲分割開來。
  • 可以消除龐大的條件分支語句。狀態模式通過把各種狀態轉移邏輯分佈到State的子類之間,來減少相互間的依賴。

缺點:

子類越多會帶來類膨脹的問題


C++實現

舉例:工作流開發

在軟件開發過程中,一個任務(用戶故事)都要經過需求、開發、測試、驗收等階段,不同的階段需要不同的人做相應的事,每個階段相當於一個狀態,此時用狀態模式比較合適。

類圖:
                

代碼:

/*!
*@file    State.h
*@brief   狀態模式
*/

#ifndef STATE_H
#define STATE_H

#include <iostream>

// 狀態類
class State
{
public:
    State() {}
    virtual ~State() {}
    virtual void Process() = 0; 

};

// 需求
class RequestState : public State
{
public:
    RequestState() {}
    ~RequestState() {}
    void Process()
    {
        std::cout << "需求整理中" << std::endl;
    }
};

// 開發
class DevelopState : public State
{
public:
    DevelopState() {}
    ~DevelopState() {}
    void Process()
    {
        std::cout << "開發中" << std::endl;
    }
};

// 測試
class TestState : public State
{
public:
    TestState() {}
    ~TestState() {}
    void Process()
    {
        std::cout << "測試中" << std::endl;
    }
};

// 驗收
class AcceptState : public State
{
public:
    AcceptState() {}
    ~AcceptState() {}
    void Process()
    {
        std::cout << "驗收中" << std::endl;
    }
};

// 任務
class UserStory
{
public:
    UserStory(State* state): m_state(state)
    {

    }

    ~UserStory()
    {
        if (m_state) 
        {
            delete m_state;
            m_state = nullptr;
        }
    }

    void SetState(State* state)
    {
        if (m_state)
            delete m_state;
        m_state = state;
    }

    State* GetState()
    {
        return m_state;
    }

    void Process()
    {
        m_state->Process();
    }

private:
    State* m_state;  // 內部狀態
};


void StateTest()
{
    UserStory* pUserStory = new UserStory(new RequestState);
    pUserStory->Process();

    pUserStory->SetState(new DevelopState);
    pUserStory->Process();

    pUserStory->SetState(new TestState);
    pUserStory->Process();

    pUserStory->SetState(new AcceptState);
    pUserStory->Process();

    delete pUserStory;
    pUserStory = nullptr;
}

#endif // STATE_H

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章