閱讀778 返回首頁    go 阿裏雲 go 技術社區[雲棲]


C++ State 設計模式

C++ State 設計模式

 

 

演示源代碼下載

 

 

 設計模式看的太快不利於消化,一方麵是最近比較忙,另一方麵是想讓自己多消化消化自己所看的東西。所以本周隻看了一個Sate設計模式

 

 

State模式的意圖有2點:

1. 分散邏輯判斷和處理。

對於State來說,無非就是狀態的切換。說白了最終結果和switch/case差不多。對於少量的狀態判斷和邏輯處理,switch還行。但是對於一個較大的項目而且條件判斷比較複雜,這個時候switch不僅效率低下,而且無法控製。State模式巧妙的將邏輯判斷和處理放到狀態對象中,而不是把條件判斷和狀態切換放在Context上下文中,從而分散了邏輯判斷和處理。如果要更改邏輯,Context就不需要改動,隻改動State類即可。

2. 去耦。我想這應該是Gof 設計模式的核心。

 

 

類圖如下:

 

                           

 

State模式中,將條件判斷和狀態切換放在State的派生類中。這樣降低了Context邏輯判斷的複雜和依賴,降低了耦合度。

 

 

主要實現代碼:

 

 

 //Context.h #pragma once class State; class Context { friend class State; public: Context(void); ~Context(void); public: void OperationInterfaceA(); void OperationInterfaceB(); protected: void ChangeState(State *pState);//狀態切換 private: State *__m_pState;//維護一個State基類指針 };

 

 

 

//Context.cpp #include "Context.h" #include "State.h" #include "ConcreteStateA.h" Context::Context(void) { __m_pState = ConcreteStateA::SInstance(); } Context::~Context(void) { delete __m_pState; __m_pState; } void Context::OperationInterfaceA() { __m_pState->OperationInterfaceA(this); } void Context::OperationInterfaceB() { __m_pState->OperationInterfaceB(this); } void Context::ChangeState(State *pState) { __m_pState = pState; }

 

 

//State.h #pragma once class Context; class State { public: State(void); virtual ~State(void); public: virtual void OperationInterfaceA(Context *pCxt){} virtual void OperationInterfaceB(Context *pCxt){} virtual void Handle(); virtual void ChangeState(State *pSt, Context *pCxt); };

 

 

//State.cpp #include "State.h" #include "Context.h" State::State(void) { } State::~State(void) { } void State::Handle() { } void State::ChangeState(State *pSt, Context *pCxt) { pCxt->__m_pState = pSt; }

 

 

//ConcreteStateA.h #pragma once #include "state.h" class ConcreteStateA : public State { public: static ConcreteStateA *SInstance(); ~ConcreteStateA(void); public: void Handle(); void OperationInterfaceA(Context *pCxt); private: ConcreteStateA(void); static ConcreteStateA *__m_spInstance; };

 

 

//ConcreteStateA.cpp #include <iostream> #include "ConcreteStateA.h" #include "ConcreteStateB.h" using namespace std; ConcreteStateA* ConcreteStateA::__m_spInstance =NULL; ConcreteStateA::ConcreteStateA(void) { } ConcreteStateA::~ConcreteStateA(void) { if (__m_spInstance != NULL) { delete __m_spInstance; __m_spInstance = NULL; } } ConcreteStateA* ConcreteStateA::SInstance() { if (__m_spInstance == NULL) { __m_spInstance = new ConcreteStateA(); } return __m_spInstance; } void ConcreteStateA::Handle() { cout << "Hi, I am in the StateA" << endl; } void ConcreteStateA::OperationInterfaceA(Context *pCxt) { Handle(); ChangeState(ConcreteStateB::SInstance(), pCxt);//狀態切換邏輯處理 }

 

 

 

//ConcreteStateB.h #pragma once #include "state.h" class ConcreteStateB : public State { public: static ConcreteStateB* SInstance(); ~ConcreteStateB(void); public: void Handle(); void OperationInterfaceB(Context *pCxt); private: ConcreteStateB(void); static ConcreteStateB *__m_sInstance; };

 

 

//ConcreteStateB.cpp #include <iostream> #include "ConcreteStateB.h" #include "ConcreteStateA.h" using namespace std; ConcreteStateB* ConcreteStateB::__m_sInstance = NULL; ConcreteStateB::ConcreteStateB(void) { } ConcreteStateB::~ConcreteStateB(void) { if (__m_sInstance != NULL) { delete __m_sInstance; __m_sInstance = NULL; } } ConcreteStateB* ConcreteStateB::SInstance() { if (__m_sInstance == NULL) { __m_sInstance = new ConcreteStateB(); } return __m_sInstance; } void ConcreteStateB::Handle() { cout << "Hi, I am in the StateB" << endl; } void ConcreteStateB::OperationInterfaceB(Context *pCxt) { Handle(); State::ChangeState(ConcreteStateA::SInstance(), pCxt); }

 

 

 

//main.cpp #include <iostream> #include "Context.h" #include "ConcreteStateA.h" #include "ConcreteStateB.h" using namespace std; int main(void) { Context txt; txt.OperationInterfaceA(); txt.OperationInterfaceB(); txt.OperationInterfaceA(); }

 

 

輸出如下:

 

Hi, I am in the StateA

Hi, I am in the StateB

Hi, I am in the StateA

 

 

 

演示源代碼下載

 

 

 

 

最後更新:2017-04-02 06:51:38

  上一篇:go 360軟件管家解除文件關聯
  下一篇:go warning C4150: 刪除指向不完整“XXX”類型的指針;沒有調用析構函數