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


State狀態模式
作用:當一個對象的內在狀態改變時允許改變其行為,這個對象看起來像是改變了其類。

UML圖如下:


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

狀態模式主要解決的是當控制一個對象狀態轉換的條件表達式過於復雜時的情況。把狀態的判斷邏輯轉移到表示不同狀態的一系列類當中,可以把復雜的判斷邏輯簡化。

狀態模式的好處是將與特定狀態相關的行為局部化,並且將不同狀態的行為分割開來。

將特定的狀態相關的行為都放入一個對象中,由於所有與狀態相關的代碼都存在於某個ConcreteState中,所以通過定義新的子類可以很容易地增加新的狀態和轉換。

可以消除龐大的條件分支語句。狀態模式通過把各種狀態轉移邏輯分布到State的子類之間,來減少相互間的依賴。

當一個對象的行為取決於它的狀態,並且它必須在運行時刻根據狀態改變它的行為時,就可以考慮使用狀態模式。
另外如果業務需求某項業務有多個狀態,通常都是一些枚舉常量,狀態的變化都是依靠大量的多分支判斷語句來實現,此時應該考慮將每一種業務狀態定義為一個State的子類。這樣這些對象就可以不依賴於其他對象兒獨立變化了。

代碼如下:

State.h

 1 #ifndef _STATE_H_
 2 #define _STATE_H_
 3 
 4 class Context;
 5 class State
 6 {
 7 public:
 8     virtual void Handle(Context* pContext)=0;
 9     ~State();
10 protected:
11     State();
12 private:
13 };
14 
15 class ConcreteStateA : public State
16 {
17 public:
18     ConcreteStateA();
19     ~ConcreteStateA();
20     virtual void Handle(Context* pContext);
21 protected:
22 private:
23 };
24 
25 class ConcreteStateB : public State
26 {
27 public:
28     ConcreteStateB();
29     ~ConcreteStateB();
30     virtual void Handle(Context* pContext);
31 protected:
32 private:
33 };
34 
35 class ConcreteStateC : public State
36 {
37 public:
38     ConcreteStateC();
39     ~ConcreteStateC();
40     virtual void Handle(Context* pContext);
41 protected:
42 private:
43 };
44 
45 class Context
46 {
47 public:
48     Context(State* pState);
49     ~Context();
50     void Request();
51     void ChangeState(State* pState);
52 protected:
53 private:
54     State* _state;
55 };
56 
57 #endif

State.cpp

 1 #include "State.h"
 2 #include <iostream>
 3 
 4 using namespace std;
 5 
 6 State::State()
 7 {}
 8 
 9 State::~State()
10 {}
11 
12 ConcreteStateA::ConcreteStateA()
13 {}
14 
15 ConcreteStateA::~ConcreteStateA()
16 {}
17 
18 //執行該狀態的行為並改變狀態
19 void ConcreteStateA::Handle(Context* pContext)
20 {
21     cout << "ConcreteStateA" << endl;
22     pContext->ChangeState(new ConcreteStateB());
23 }
24 
25 ConcreteStateB::ConcreteStateB()
26 {}
27 
28 ConcreteStateB::~ConcreteStateB()
29 {}
30 
31 //執行該狀態的行為並改變狀態
32 void ConcreteStateB::Handle(Context* pContext)
33 {
34     cout << "ConcreteStateB" << endl;
35     pContext->ChangeState(new ConcreteStateC());
36 }
37 
38 ConcreteStateC::ConcreteStateC()
39 {}
40 
41 ConcreteStateC::~ConcreteStateC()
42 {}
43 
44 //執行該狀態的行為並改變狀態
45 void ConcreteStateC::Handle(Context* pContext)
46 {
47     cout << "ConcreteStateC" << endl;
48     pContext->ChangeState(new ConcreteStateA());
49 }
50 
51 //定義_state的初始狀態
52 Context::Context(State* pState)
53 {
54     this->_state = pState;
55 }
56 
57 Context::~Context()
58 {}
59 
60 //對請求做處理,並設置下一狀態
61 void Context::Request()
62 {
63     if(NULL != this->_state)
64     {
65         this->_state->Handle(this);
66     }
67 }
68 
69 //改變狀態
70 void Context::ChangeState(State* pState)
71 {
72     this->_state = pState;
73 }

main.cpp

 1 #include "State.h"
 2 
 3 int main()
 4 {
 5     State* pState = new ConcreteStateA();
 6     Context* pContext = new Context(pState);
 7     pContext->Request();
 8     pContext->Request();
 9     pContext->Request();
10     pContext->Request();
11     pContext->Request();
12     return 0;
13 }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM