設計模式C++實現(16)——狀態模式

分類: 軟件設計模式c++實現 50人閱讀 評論(0) 收藏 舉報
 軟件領域中的設計模式爲開發人員提供了一種使用專家設計經驗的有效途徑。設計模式中運用了面向對象編程語言的重要特性:封裝、繼承、多態,真正領悟設計模式的精髓是可能一個漫長的過程,需要大量實踐經驗的積累。最近看設計模式的書,對於每個模式,用C++寫了個小例子,加深一下理解。主要參考《大話設計模式》和《設計模式:可複用面向對象軟件的基礎》兩本書。本文介紹狀態模式的實現。

       狀態模式:允許一個對象在其內部狀態改變時改變它的行爲。對象看起來似乎修改了它的類。它有兩種使用情況:(1)一個對象的行爲取決於它的狀態, 並且它必須在運行時刻根據狀態改變它的行爲。(2)一個操作中含有龐大的多分支的條件語句,且這些分支依賴於該對象的狀態。本文的例子爲第一種情況,以戰爭爲例,假設一場戰爭需經歷四個階段:前期、中期、後期、結束。當戰爭處於不同的階段,戰爭的行爲是不一樣的,也就說戰爭的行爲取決於所處的階段,而且隨着時間的推進是動態變化的。下面給出相應的UML圖。


       實現的代碼比較簡單,給出War類和State類,War類中含State對象(指針形式)。

  1. class War;  
  2. class State   
  3. {  
  4. public:  
  5.     virtual void Prophase() {}  
  6.     virtual void Metaphase() {}  
  7.     virtual void Anaphase() {}  
  8.     virtual void End() {}  
  9.     virtual void CurrentState(War *war) {}  
  10. };  
  11. //戰爭   
  12. class War  
  13. {  
  14. private:  
  15.     State *m_state;  //目前狀態   
  16.     int m_days;      //戰爭持續時間  
  17. public:  
  18.     War(State *state): m_state(state), m_days(0) {}  
  19.     ~War() { delete m_state; }  
  20.     int GetDays() { return m_days; }  
  21.     void SetDays(int days) { m_days = days; }  
  22.     void SetState(State *state) { delete m_state; m_state = state; }  
  23.     void GetState() { m_state->CurrentState(this); }  
  24. };  
  1. class War;  
  2. class State   
  3. {  
  4. public:  
  5.     virtual void Prophase() {}  
  6.     virtual void Metaphase() {}  
  7.     virtual void Anaphase() {}  
  8.     virtual void End() {}  
  9.     virtual void CurrentState(War *war) {}  
  10. };  
  11. //戰爭  
  12. class War  
  13. {  
  14. private:  
  15.     State *m_state;  //目前狀態  
  16.     int m_days;      //戰爭持續時間  
  17. public:  
  18.     War(State *state): m_state(state), m_days(0) {}  
  19.     ~War() { delete m_state; }  
  20.     int GetDays() { return m_days; }  
  21.     void SetDays(int days) { m_days = days; }  
  22.     void SetState(State *state) { delete m_state; m_state = state; }  
  23.     void GetState() { m_state->CurrentState(this); }  
  24. };  

           給出具體的狀態類:

  1. //戰爭結束   
  2. class EndState: public State  
  3. {  
  4. public:  
  5.     void End(War *war) //結束階段的具體行爲  
  6.     {  
  7.         cout<<"戰爭結束"<<endl;  
  8.     }  
  9.     void CurrentState(War *war) { End(war); }  
  10. };  
  11. //後期   
  12. class AnaphaseState: public State  
  13. {  
  14. public:  
  15.     void Anaphase(War *war) //後期的具體行爲  
  16.     {  
  17.         if(war->GetDays() < 30)  
  18.             cout<<"第"<<war->GetDays()<<"天:戰爭後期,雙方拼死一搏"<<endl;  
  19.         else  
  20.         {  
  21.             war->SetState(new EndState());  
  22.             war->GetState();  
  23.         }  
  24.     }  
  25.     void CurrentState(War *war) { Anaphase(war); }  
  26. };  
  27. //中期   
  28. class MetaphaseState: public State  
  29. {  
  30. public:  
  31.     void Metaphase(War *war) //中期的具體行爲  
  32.     {  
  33.         if(war->GetDays() < 20)  
  34.             cout<<"第"<<war->GetDays()<<"天:戰爭中期,進入相持階段,雙發各有損耗"<<endl;  
  35.         else  
  36.         {  
  37.             war->SetState(new AnaphaseState());  
  38.             war->GetState();  
  39.         }  
  40.     }  
  41.     void CurrentState(War *war) { Metaphase(war); }  
  42. };  
  43. //前期   
  44. class ProphaseState: public State  
  45. {  
  46. public:  
  47.     void Prophase(War *war)  //前期的具體行爲  
  48.     {  
  49.         if(war->GetDays() < 10)  
  50.             cout<<"第"<<war->GetDays()<<"天:戰爭初期,雙方你來我往,互相試探對方"<<endl;  
  51.         else  
  52.         {  
  53.             war->SetState(new MetaphaseState());  
  54.             war->GetState();  
  55.         }  
  56.     }  
  57.     void CurrentState(War *war) { Prophase(war); }  
  58. };  
  1. //戰爭結束  
  2. class EndState: public State  
  3. {  
  4. public:  
  5.     void End(War *war) //結束階段的具體行爲  
  6.     {  
  7.         cout<<"戰爭結束"<<endl;  
  8.     }  
  9.     void CurrentState(War *war) { End(war); }  
  10. };  
  11. //後期  
  12. class AnaphaseState: public State  
  13. {  
  14. public:  
  15.     void Anaphase(War *war) //後期的具體行爲  
  16.     {  
  17.         if(war->GetDays() < 30)  
  18.             cout<<"第"<<war->GetDays()<<"天:戰爭後期,雙方拼死一搏"<<endl;  
  19.         else  
  20.         {  
  21.             war->SetState(new EndState());  
  22.             war->GetState();  
  23.         }  
  24.     }  
  25.     void CurrentState(War *war) { Anaphase(war); }  
  26. };  
  27. //中期  
  28. class MetaphaseState: public State  
  29. {  
  30. public:  
  31.     void Metaphase(War *war) //中期的具體行爲  
  32.     {  
  33.         if(war->GetDays() < 20)  
  34.             cout<<"第"<<war->GetDays()<<"天:戰爭中期,進入相持階段,雙發各有損耗"<<endl;  
  35.         else  
  36.         {  
  37.             war->SetState(new AnaphaseState());  
  38.             war->GetState();  
  39.         }  
  40.     }  
  41.     void CurrentState(War *war) { Metaphase(war); }  
  42. };  
  43. //前期  
  44. class ProphaseState: public State  
  45. {  
  46. public:  
  47.     void Prophase(War *war)  //前期的具體行爲  
  48.     {  
  49.         if(war->GetDays() < 10)  
  50.             cout<<"第"<<war->GetDays()<<"天:戰爭初期,雙方你來我往,互相試探對方"<<endl;  
  51.         else  
  52.         {  
  53.             war->SetState(new MetaphaseState());  
  54.             war->GetState();  
  55.         }  
  56.     }  
  57.     void CurrentState(War *war) { Prophase(war); }  
  58. };  
         使用方式:
  1. //測試案例   
  2. int main()  
  3. {  
  4.     War *war = new War(new ProphaseState());  
  5.     for(int i = 1; i < 40;i += 5)  
  6.     {  
  7.         war->SetDays(i);  
  8.         war->GetState();  
  9.     }  
  10.     delete war;  
  11.     return 0;  
  12. }  
  1. //測試案例  
  2. int main()  
  3. {  
  4.     War *war = new War(new ProphaseState());  
  5.     for(int i = 1; i < 40;i += 5)  
  6.     {  
  7.         war->SetDays(i);  
  8.         war->GetState();  
  9.     }  
  10.     delete war;  
  11.     return 0;  
  12. }  
     本人享有博客文章的版權,轉載請標明出處 http://blog.csdn.net/wuzhekai1985

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